Advertisement
Guest User

Untitled

a guest
Feb 25th, 2015
345
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 11.11 KB | None | 0 0
  1. -- SIMPLE INTERPRETER; reads each byte of the string and moves back and forth around the string for loops. Pretty slow.
  2.  
  3. local function bf(code, input)
  4.     local output = ""
  5.     local mem = {0}
  6.     local ptr = 1
  7.    
  8.     local codeloc = 1
  9.     local inputloc = 1
  10.    
  11.     local INCREMENT = (">"):byte()
  12.     local DECREMENT = ("<"):byte()
  13.     local ADD = ("+"):byte()
  14.     local SUB = ("-"):byte()
  15.     local INPUT = (","):byte()
  16.     local OUTPUT = ("."):byte()
  17.     local STARTWHILE = ("["):byte()
  18.     local STOPWHILE = ("]"):byte()
  19.    
  20.     -- TODO: check code for matching []
  21.     -- TODO: remove non-bf characters from code before beginning
  22.    
  23.     while codeloc <= code:len() do
  24.         local instruction = code:byte(codeloc)
  25.         if     instruction == INCREMENT then
  26.             ptr = $1+1
  27.             mem[ptr] = $1 or 0
  28.         elseif instruction == DECREMENT then
  29.             ptr = $1-1
  30.             mem[ptr] = $1 or 0
  31.         elseif instruction == ADD then
  32.             mem[ptr] = ($1+1) & 255
  33.         elseif instruction == SUB then
  34.             mem[ptr] = ($1-1) & 255
  35.         elseif instruction == INPUT then
  36.             if inputloc <= input:len() then
  37.                 mem[ptr] = input:byte(inputloc)
  38.                 inputloc = $1+1
  39.             end
  40.         elseif instruction == OUTPUT then
  41.             output = $1 .. string.char(mem[ptr])
  42.         elseif instruction == STARTWHILE then
  43.             if not mem[ptr] then
  44.                 local deep = 1
  45.                 while deep do
  46.                     codeloc = $1+1
  47.                     instruction = code:byte(codeloc)
  48.                     if instruction == STARTWHILE then
  49.                         deep = $1+1
  50.                     elseif instruction == STOPWHILE then
  51.                         deep = $1-1
  52.                     end
  53.                 end
  54.             end
  55.         elseif instruction == STOPWHILE then
  56.             if mem[ptr] then
  57.                 local deep = 1
  58.                 while deep do
  59.                     codeloc = $1-1
  60.                     instruction = code:byte(codeloc)
  61.                     if instruction == STOPWHILE then
  62.                         deep = $1+1
  63.                     elseif instruction == STARTWHILE then
  64.                         deep = $1-1
  65.                     end
  66.                 end
  67.             end
  68.         elseif instruction == ("#"):byte() then
  69.             local d = "ptr="..ptr.."  "
  70.             for i=0,32 do
  71.                 d = $1..(mem[i] or 0).." "
  72.             end
  73.             print(d)
  74.             return nil
  75.         end
  76.         codeloc = $1+1
  77.     end
  78.    
  79.     return output
  80. end
  81.  
  82. rawset(_G, "brainfuck", bf)
  83.  
  84.  
  85.  
  86. -- ADVANCED INTERPRETER; converts string into a table with instructions, with loops being embedded tables and repeated instructions combined into one call. Much faster than the simple implementation.
  87.  
  88. local BF = {
  89.     ADD = 1,
  90.     SHIFT = 2,
  91.     IN = 3,
  92.     OUT = 4,
  93.     LOOP = 5,
  94.     DEBUG = 6
  95. }
  96.  
  97. local function bf_process(str)
  98.     local ret = {}
  99.    
  100.     local pos = 0
  101.    
  102.     local INCREMENT = (">"):byte()
  103.     local DECREMENT = ("<"):byte()
  104.     local ADD = ("+"):byte()
  105.     local SUB = ("-"):byte()
  106.     local INPUT = (","):byte()
  107.     local OUTPUT = ("."):byte()
  108.     local STARTWHILE = ("["):byte()
  109.     local STOPWHILE = ("]"):byte()
  110.     local DEBUG = ("#"):byte()
  111.    
  112.     local bf_parse
  113.     bf_parse = function(tbl)
  114.         pos = $1+1
  115.         local k = str:byte(pos)
  116.         while true do
  117.             if k == ADD or k == SUB then
  118.                 local total = 1
  119.                 if k == SUB then total = -1 end
  120.                 while true do
  121.                     pos = $1+1
  122.                     k = str:byte(pos)
  123.                     if k == ADD then
  124.                         total = $1+1
  125.                     elseif k == SUB then
  126.                         total = $1-1
  127.                     else
  128.                         break
  129.                     end
  130.                 end
  131.                 table.insert(tbl,{[0] = BF.ADD, [1] = total})
  132.             elseif k == INCREMENT or k == DECREMENT then
  133.                 local total = 1
  134.                 if k == DECREMENT then total = -1 end
  135.                 while true do
  136.                     pos = $1+1
  137.                     k = str:byte(pos)
  138.                     if k == INCREMENT then
  139.                         total = $1+1
  140.                     elseif k == DECREMENT then
  141.                         total = $1-1
  142.                     else
  143.                         break
  144.                     end
  145.                 end
  146.                 table.insert(tbl,{[0] = BF.SHIFT, [1] = total})
  147.             elseif k == INPUT or k == OUTPUT or k == DEBUG then
  148.                 if k == INPUT then
  149.                     table.insert(tbl,{[0] = BF.IN})
  150.                 elseif k == OUTPUT then
  151.                     table.insert(tbl,{[0] = BF.OUT})
  152.                 else
  153.                     table.insert(tbl,{[0] = BF.DEBUG})
  154.                 end
  155.                 pos = $1+1
  156.                 k = str:byte(pos)
  157.             elseif k == STOPWHILE or k == nil then
  158.                 pos = $1+1
  159.                 return tbl
  160.             elseif k == STARTWHILE then
  161.                 local t = {}
  162.                 bf_parse(t)
  163.                 t[0] = BF.LOOP
  164.                 table.insert(tbl, t)
  165.                 k = str:byte(pos)
  166.             else
  167.                 pos = $1+1
  168.                 k = str:byte(pos)
  169.             end
  170.         end
  171.     end
  172.    
  173.     bf_parse(ret)
  174.    
  175.     --[[ debug (warning: often crashes the game after being run)
  176.     local dbgp
  177.     dbgp = function(tbl,depth)
  178.         local ret = "{"
  179.         depth = $1+1
  180.         for k,v in pairs(tbl) do
  181.             ret = $1 .. "\n" .. ("  "):rep(depth) .. k .. " = "
  182.             if type(v) == "table" then
  183.                 ret = $1 .. dbgp(v,depth)
  184.             else
  185.                 ret = $1 .. v
  186.             end
  187.             ret = $1 .. ","
  188.         end
  189.         depth = $1-1
  190.         ret = $1 .. "\n" .. ("  "):rep(depth) .. "}"
  191.         return ret
  192.     end
  193.     print(dbgp(ret,0))]]
  194.    
  195.     return ret
  196. end
  197.  
  198. local function bf_adv(code, input)
  199.     local output = ""
  200.     local mem = {0}
  201.     local ptr = 1
  202.    
  203.     local inputloc = 1
  204.    
  205.     local bf_run
  206.     bf_run = function(tbl)
  207.         for _,i in ipairs(tbl) do
  208.             local c = i[0]
  209.             if     c == BF.ADD then
  210.                 mem[ptr] = ($1+i[1]) & 255
  211.             elseif c == BF.SHIFT then
  212.                 ptr = $1+i[1]
  213.                 mem[ptr] = $1 or 0
  214.             elseif c == BF.IN then
  215.                 if inputloc <= input:len() then
  216.                     mem[ptr] = input:byte(inputloc)
  217.                     inputloc = $1+1
  218.                 end
  219.             elseif c == BF.OUT then
  220.                 output = $1 .. string.char(mem[ptr])
  221.             elseif c == BF.LOOP then
  222.                 while mem[ptr] do bf_run(i) end
  223.             else -- BF.DEBUG
  224.                 local d = "ptr="..ptr.."  "
  225.                 for i=0,100 do
  226.                     d = $1..(mem[i] or 0).." "
  227.                 end
  228.                 print(d)
  229.             end
  230.         end
  231.     end
  232.     bf_run(code)
  233.    
  234.     return output
  235. end
  236.  
  237. rawset(_G, "brainfuck", function(code, input)
  238.     return bf_adv(bf_process(code), input)
  239. end)
  240.  
  241.  
  242.  
  243. -- Sample scripts and test console commands
  244.  
  245. --print(brainfuck("++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.")) -- Hello World program
  246. --print(brainfuck(">>>+[[-]>>[-]++>+>+++++++[<++++>>++<-]++>>+>+>+++++[>++>++++++<<-]+>>>,<++[[>[->>]<[>>]<<-]<[<]<+>>[>]>[<+>-[[<+>-]>]<[[[-]<]++<-[<+++++++++>[<->-]>>]>>]]<<]<]<[[<]>[[>]>>[>>]+[<<]<[<]<+>>-]>[>]+[->>]<<<<[[<<]<[<]+<<[+>+<<-[>-->+<<-[>+<[>>+<<-]]]>[<+>-]<]++>>-->[>]>>[>>]]<<[>>+<[[<]<]>[[<<]<[<]+[-<+>>-[<<+>++>-[<->[<<+>>-]]]<[>+<-]>]>[>]>]>[>>]>>]<<[>>+>>+>>]<<[->>>>>>>>]<<[>.>>>>>>>]<<[>->>>>>]<<[>,>>>]<<[>+>]<<[+<<]<]", "++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.!")) -- Brainfuck interpreter written in Brainfuck, with a Hello World program as input
  247.  
  248. -- brainfuck tests
  249. --print(brainfuck(">,>+++++++++,>+++++++++++[<++++++<++++++<+>>>-]<<.>.<<-.>.>.<<.", "\n"))
  250. --print(brainfuck("++++[>++++++<-]>[>+++++>+++++++<<-]>>++++<[[>[[>>+<<-]<]>>>-]>-[>+>+<<-]>]+++++[>+++++++<<++>-]>.<<."))
  251. --print(brainfuck("[]++++++++++[>>+>+>++++++[<<+<+++>>>-]<<<<-]\n"..'"A*$";?@![#>>+<<]>[>>]<<<<[>++<[-]]>.>.'))
  252.  
  253. COM_AddCommand("brainfuck", function(player, code, input)
  254.     CONS_Printf(player, brainfuck(code, input))
  255. end)
  256.  
  257. COM_AddCommand("hashtest", function(player, input)
  258.     local code = [[
  259.  
  260. [A PASSWORD HASHING SCRIPT FOR NOTHING USEFUL, lmao this is fucking stupid (written in brainfuck because lol)
  261.  
  262. spaces:
  263.  
  264. -1: loop counter (if using this in a bf implemention without wrapping, just add a > to the start of the program)
  265. 0-1: space for printing out characters
  266. 2-17: space for holding bytes
  267. 18: null padding
  268. 19-22: registers for handling shit
  269. 23+: input]
  270.  
  271. Shift to 23 while filling hash table with random junk along the way
  272.     >
  273.    
  274.     >++++++++++
  275.     >+++++
  276.     >+++++++++++++++++++++++++++++++++++++++
  277.     >-----------------------
  278.     >------
  279.     >+++++++++++++++++++++++++++++++++++++++++++++++++++++
  280.     >---------------------
  281.     >++
  282.     >-------------------------------------------------------------------------------------
  283.     >+++++++++++++++++++++++++++++++++
  284.     >+++++++++
  285.     >--------------------------------------------
  286.     >+++++++++++++++
  287.     >-------------------------------
  288.     >------------
  289.     >--
  290.    
  291.     > NOW AT NULL PADDING >>>> NOW AT LAST HANDLING REGISTER > NOW AT INPUT START
  292.  
  293. Put all input into remaining memory
  294. ,[>,]
  295.  
  296. Slide back to 22
  297. <[<]
  298.  
  299. Now go forward to start of input
  300. >
  301.  
  302. And start loop
  303. [
  304.     TODO: hashing
  305.    
  306.     OKAY! Let's start by multiplying this char with next char plus one and put it in register 3
  307.    
  308.         Start that by copying next char into register 4 (will use register 3 to do this without destroying next char spot)
  309.         >[-<<+<+>>>]<<<[->>>+<<<]>
  310.         CURRENT LOCATION: ptr=22 (register 4)
  311.        
  312.         Add one to that value
  313.         +
  314.        
  315.         Now do the multiplication
  316.         [>
  317.             Do the same copying thing but this time into register 3 (will end up adding) and using register 2 as the holder
  318.             [-<<+<+>>>]<<<[->>>+<<<]
  319.            
  320.             Now move up to register 4 and decrement then loop back
  321.             >>-
  322.         ]
  323.     CURRENT STATUS: ptr=22 regs=0 0 (product of multiplication) 0
  324.    
  325.     Let's move product to register 1!
  326.     <[-<<+>>]<<
  327.     CURRENT LOCATION: ptr=19
  328.    
  329.     Now let's do something PRODUCT times
  330.     [
  331.         But what to do?
  332.        
  333.         Let's add some weird freaky value to each hash spot!
  334.             < <<<< <<<< <<<< <<<<
  335.            
  336.             +++>
  337.             -->
  338.             ++++++>
  339.             +>
  340.            
  341.             --->
  342.             >
  343.             ++>
  344.             ++++++++++++++>
  345.            
  346.             ------>
  347.             +>
  348.             ++>
  349.             +++>
  350.            
  351.             -->
  352.             ------>
  353.             +>
  354.             ++>>
  355.         CURRENT LOCATION: ptr=19
  356.    
  357.         (ASSUMED LOCATION: ptr=19)
  358.         But let's not use product directly: let's decrement it by 9 (this doesn't multiply evenly into 256 so we'll eventually hit 0 anyway)
  359.         --- --- ---
  360.     ]
  361.    
  362.     Now finally, let's cycle the hash around a cycle
  363.         <
  364.         <[->+<]
  365.         <[->+<]
  366.         <[->+<]
  367.         <[->+<]
  368.         <[->+<]
  369.         <[->+<]
  370.         <[->+<]
  371.         <[->+<]
  372.         <[->+<]
  373.         <[->+<]
  374.         <[->+<]
  375.         <[->+<]
  376.         <[->+<]
  377.         <[->+<]
  378.         <[->+<]
  379.         <[->+<]
  380.         >>>>>>>>>>>>>>>>
  381.         [-<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>]
  382.    
  383.     >>>>>
  384.    
  385.    
  386.    
  387.     (ASSUMED LOCATION: ptr=23 val=0 LAST HANDLING REGISTER MUST BE ZERO)
  388.     Now shift input back toward us
  389.     [-]
  390.     >[
  391.         We have input left to move so shift it back one then advance pointer by one
  392.         [-<+>]>
  393.     ]
  394.    
  395.     Now go back to where input is!
  396.     <<[<]>
  397. ] (ASSUMED LOCATION: ptr=23 val=0 if loop ending)
  398.  
  399. OKAY NOW WE'RE DONE WITH PARSING THE HASH so now we just have to render it
  400. For ease on myself 0 will be A and 15 will be P instead of 0 to 9 then A to F
  401.  
  402. Start by going back to ptr=0
  403. <<<< <<<< <<<< <<<< <<<< <<<
  404.  
  405. Now let's go back then add 16 for the number of loops we need
  406. < ++++ ++++ ++++ ++++
  407.  
  408. LOOP
  409. [>
  410.    
  411.     Move to next part of hash
  412.     >>
  413.    
  414.     Count down
  415.     [<
  416.         Add 1 to higher digit
  417.         <+>
  418.        
  419.         Subtract 15 from lower digit
  420.         ----- ----- -----
  421.        
  422.         If not 0 (original value was not 15) then
  423.         [
  424.             Pull the 1 back off the higher digit
  425.             <->
  426.            
  427.             Add 16 (total of adding 1)
  428.             ++++ ++++ ++++ ++++
  429.            
  430.             Shift value from 1 to 18
  431.             [->>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<]
  432.         ]
  433.        
  434.         Copy from 18 back to 1 just in case above was true (does nothing if it wasn't)
  435.         >>>>>>>>>>>>>>>>>[-<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>]<<<<<<<<<<<<<<<<<
  436.     >-]
  437.    
  438.     Add 65 (A) to each then print then wipe
  439.     << ++++++++ ++++++++ ++++++++ ++++++++ ++++++++ ++++++++ ++++++++ ++++++++ + . [-]
  440.     > ++++++++ ++++++++ ++++++++ ++++++++ ++++++++ ++++++++ ++++++++ ++++++++ + . [-]
  441.    
  442.     Now pull hash toward us (this will need repeated 15 times)
  443.     >
  444.         >[-<+>]
  445.         >[-<+>]
  446.         >[-<+>]
  447.         >[-<+>]
  448.         >[-<+>]
  449.         >[-<+>]
  450.         >[-<+>]
  451.         >[-<+>]
  452.         >[-<+>]
  453.         >[-<+>]
  454.         >[-<+>]
  455.         >[-<+>]
  456.         >[-<+>]
  457.         >[-<+>]
  458.         >[-<+>]
  459.    
  460.     Go back where we were before
  461.     <<<< <<<< <<<< <<<<
  462.    
  463.     Then one more
  464.     <
  465.    
  466.     And let loop continue
  467. <-]
  468.  
  469.  
  470. ]]
  471.    
  472.     CONS_Printf(player, bf_adv(bf_process(code), input))
  473. end)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement