Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- SIMPLE INTERPRETER; reads each byte of the string and moves back and forth around the string for loops. Pretty slow.
- local function bf(code, input)
- local output = ""
- local mem = {0}
- local ptr = 1
- local codeloc = 1
- local inputloc = 1
- local INCREMENT = (">"):byte()
- local DECREMENT = ("<"):byte()
- local ADD = ("+"):byte()
- local SUB = ("-"):byte()
- local INPUT = (","):byte()
- local OUTPUT = ("."):byte()
- local STARTWHILE = ("["):byte()
- local STOPWHILE = ("]"):byte()
- -- TODO: check code for matching []
- -- TODO: remove non-bf characters from code before beginning
- while codeloc <= code:len() do
- local instruction = code:byte(codeloc)
- if instruction == INCREMENT then
- ptr = $1+1
- mem[ptr] = $1 or 0
- elseif instruction == DECREMENT then
- ptr = $1-1
- mem[ptr] = $1 or 0
- elseif instruction == ADD then
- mem[ptr] = ($1+1) & 255
- elseif instruction == SUB then
- mem[ptr] = ($1-1) & 255
- elseif instruction == INPUT then
- if inputloc <= input:len() then
- mem[ptr] = input:byte(inputloc)
- inputloc = $1+1
- end
- elseif instruction == OUTPUT then
- output = $1 .. string.char(mem[ptr])
- elseif instruction == STARTWHILE then
- if not mem[ptr] then
- local deep = 1
- while deep do
- codeloc = $1+1
- instruction = code:byte(codeloc)
- if instruction == STARTWHILE then
- deep = $1+1
- elseif instruction == STOPWHILE then
- deep = $1-1
- end
- end
- end
- elseif instruction == STOPWHILE then
- if mem[ptr] then
- local deep = 1
- while deep do
- codeloc = $1-1
- instruction = code:byte(codeloc)
- if instruction == STOPWHILE then
- deep = $1+1
- elseif instruction == STARTWHILE then
- deep = $1-1
- end
- end
- end
- elseif instruction == ("#"):byte() then
- local d = "ptr="..ptr.." "
- for i=0,32 do
- d = $1..(mem[i] or 0).." "
- end
- print(d)
- return nil
- end
- codeloc = $1+1
- end
- return output
- end
- rawset(_G, "brainfuck", bf)
- -- 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.
- local BF = {
- ADD = 1,
- SHIFT = 2,
- IN = 3,
- OUT = 4,
- LOOP = 5,
- DEBUG = 6
- }
- local function bf_process(str)
- local ret = {}
- local pos = 0
- local INCREMENT = (">"):byte()
- local DECREMENT = ("<"):byte()
- local ADD = ("+"):byte()
- local SUB = ("-"):byte()
- local INPUT = (","):byte()
- local OUTPUT = ("."):byte()
- local STARTWHILE = ("["):byte()
- local STOPWHILE = ("]"):byte()
- local DEBUG = ("#"):byte()
- local bf_parse
- bf_parse = function(tbl)
- pos = $1+1
- local k = str:byte(pos)
- while true do
- if k == ADD or k == SUB then
- local total = 1
- if k == SUB then total = -1 end
- while true do
- pos = $1+1
- k = str:byte(pos)
- if k == ADD then
- total = $1+1
- elseif k == SUB then
- total = $1-1
- else
- break
- end
- end
- table.insert(tbl,{[0] = BF.ADD, [1] = total})
- elseif k == INCREMENT or k == DECREMENT then
- local total = 1
- if k == DECREMENT then total = -1 end
- while true do
- pos = $1+1
- k = str:byte(pos)
- if k == INCREMENT then
- total = $1+1
- elseif k == DECREMENT then
- total = $1-1
- else
- break
- end
- end
- table.insert(tbl,{[0] = BF.SHIFT, [1] = total})
- elseif k == INPUT or k == OUTPUT or k == DEBUG then
- if k == INPUT then
- table.insert(tbl,{[0] = BF.IN})
- elseif k == OUTPUT then
- table.insert(tbl,{[0] = BF.OUT})
- else
- table.insert(tbl,{[0] = BF.DEBUG})
- end
- pos = $1+1
- k = str:byte(pos)
- elseif k == STOPWHILE or k == nil then
- pos = $1+1
- return tbl
- elseif k == STARTWHILE then
- local t = {}
- bf_parse(t)
- t[0] = BF.LOOP
- table.insert(tbl, t)
- k = str:byte(pos)
- else
- pos = $1+1
- k = str:byte(pos)
- end
- end
- end
- bf_parse(ret)
- --[[ debug (warning: often crashes the game after being run)
- local dbgp
- dbgp = function(tbl,depth)
- local ret = "{"
- depth = $1+1
- for k,v in pairs(tbl) do
- ret = $1 .. "\n" .. (" "):rep(depth) .. k .. " = "
- if type(v) == "table" then
- ret = $1 .. dbgp(v,depth)
- else
- ret = $1 .. v
- end
- ret = $1 .. ","
- end
- depth = $1-1
- ret = $1 .. "\n" .. (" "):rep(depth) .. "}"
- return ret
- end
- print(dbgp(ret,0))]]
- return ret
- end
- local function bf_adv(code, input)
- local output = ""
- local mem = {0}
- local ptr = 1
- local inputloc = 1
- local bf_run
- bf_run = function(tbl)
- for _,i in ipairs(tbl) do
- local c = i[0]
- if c == BF.ADD then
- mem[ptr] = ($1+i[1]) & 255
- elseif c == BF.SHIFT then
- ptr = $1+i[1]
- mem[ptr] = $1 or 0
- elseif c == BF.IN then
- if inputloc <= input:len() then
- mem[ptr] = input:byte(inputloc)
- inputloc = $1+1
- end
- elseif c == BF.OUT then
- output = $1 .. string.char(mem[ptr])
- elseif c == BF.LOOP then
- while mem[ptr] do bf_run(i) end
- else -- BF.DEBUG
- local d = "ptr="..ptr.." "
- for i=0,100 do
- d = $1..(mem[i] or 0).." "
- end
- print(d)
- end
- end
- end
- bf_run(code)
- return output
- end
- rawset(_G, "brainfuck", function(code, input)
- return bf_adv(bf_process(code), input)
- end)
- -- Sample scripts and test console commands
- --print(brainfuck("++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.")) -- Hello World program
- --print(brainfuck(">>>+[[-]>>[-]++>+>+++++++[<++++>>++<-]++>>+>+>+++++[>++>++++++<<-]+>>>,<++[[>[->>]<[>>]<<-]<[<]<+>>[>]>[<+>-[[<+>-]>]<[[[-]<]++<-[<+++++++++>[<->-]>>]>>]]<<]<]<[[<]>[[>]>>[>>]+[<<]<[<]<+>>-]>[>]+[->>]<<<<[[<<]<[<]+<<[+>+<<-[>-->+<<-[>+<[>>+<<-]]]>[<+>-]<]++>>-->[>]>>[>>]]<<[>>+<[[<]<]>[[<<]<[<]+[-<+>>-[<<+>++>-[<->[<<+>>-]]]<[>+<-]>]>[>]>]>[>>]>>]<<[>>+>>+>>]<<[->>>>>>>>]<<[>.>>>>>>>]<<[>->>>>>]<<[>,>>>]<<[>+>]<<[+<<]<]", "++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.!")) -- Brainfuck interpreter written in Brainfuck, with a Hello World program as input
- -- brainfuck tests
- --print(brainfuck(">,>+++++++++,>+++++++++++[<++++++<++++++<+>>>-]<<.>.<<-.>.>.<<.", "\n"))
- --print(brainfuck("++++[>++++++<-]>[>+++++>+++++++<<-]>>++++<[[>[[>>+<<-]<]>>>-]>-[>+>+<<-]>]+++++[>+++++++<<++>-]>.<<."))
- --print(brainfuck("[]++++++++++[>>+>+>++++++[<<+<+++>>>-]<<<<-]\n"..'"A*$";?@![#>>+<<]>[>>]<<<<[>++<[-]]>.>.'))
- COM_AddCommand("brainfuck", function(player, code, input)
- CONS_Printf(player, brainfuck(code, input))
- end)
- COM_AddCommand("hashtest", function(player, input)
- local code = [[
- [A PASSWORD HASHING SCRIPT FOR NOTHING USEFUL, lmao this is fucking stupid (written in brainfuck because lol)
- spaces:
- -1: loop counter (if using this in a bf implemention without wrapping, just add a > to the start of the program)
- 0-1: space for printing out characters
- 2-17: space for holding bytes
- 18: null padding
- 19-22: registers for handling shit
- 23+: input]
- Shift to 23 while filling hash table with random junk along the way
- >
- >++++++++++
- >+++++
- >+++++++++++++++++++++++++++++++++++++++
- >-----------------------
- >------
- >+++++++++++++++++++++++++++++++++++++++++++++++++++++
- >---------------------
- >++
- >-------------------------------------------------------------------------------------
- >+++++++++++++++++++++++++++++++++
- >+++++++++
- >--------------------------------------------
- >+++++++++++++++
- >-------------------------------
- >------------
- >--
- > NOW AT NULL PADDING >>>> NOW AT LAST HANDLING REGISTER > NOW AT INPUT START
- Put all input into remaining memory
- ,[>,]
- Slide back to 22
- <[<]
- Now go forward to start of input
- >
- And start loop
- [
- TODO: hashing
- OKAY! Let's start by multiplying this char with next char plus one and put it in register 3
- Start that by copying next char into register 4 (will use register 3 to do this without destroying next char spot)
- >[-<<+<+>>>]<<<[->>>+<<<]>
- CURRENT LOCATION: ptr=22 (register 4)
- Add one to that value
- +
- Now do the multiplication
- [>
- Do the same copying thing but this time into register 3 (will end up adding) and using register 2 as the holder
- [-<<+<+>>>]<<<[->>>+<<<]
- Now move up to register 4 and decrement then loop back
- >>-
- ]
- CURRENT STATUS: ptr=22 regs=0 0 (product of multiplication) 0
- Let's move product to register 1!
- <[-<<+>>]<<
- CURRENT LOCATION: ptr=19
- Now let's do something PRODUCT times
- [
- But what to do?
- Let's add some weird freaky value to each hash spot!
- < <<<< <<<< <<<< <<<<
- +++>
- -->
- ++++++>
- +>
- --->
- >
- ++>
- ++++++++++++++>
- ------>
- +>
- ++>
- +++>
- -->
- ------>
- +>
- ++>>
- CURRENT LOCATION: ptr=19
- (ASSUMED LOCATION: ptr=19)
- 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)
- --- --- ---
- ]
- Now finally, let's cycle the hash around a cycle
- <
- <[->+<]
- <[->+<]
- <[->+<]
- <[->+<]
- <[->+<]
- <[->+<]
- <[->+<]
- <[->+<]
- <[->+<]
- <[->+<]
- <[->+<]
- <[->+<]
- <[->+<]
- <[->+<]
- <[->+<]
- <[->+<]
- >>>>>>>>>>>>>>>>
- [-<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>]
- >>>>>
- (ASSUMED LOCATION: ptr=23 val=0 LAST HANDLING REGISTER MUST BE ZERO)
- Now shift input back toward us
- [-]
- >[
- We have input left to move so shift it back one then advance pointer by one
- [-<+>]>
- ]
- Now go back to where input is!
- <<[<]>
- ] (ASSUMED LOCATION: ptr=23 val=0 if loop ending)
- OKAY NOW WE'RE DONE WITH PARSING THE HASH so now we just have to render it
- For ease on myself 0 will be A and 15 will be P instead of 0 to 9 then A to F
- Start by going back to ptr=0
- <<<< <<<< <<<< <<<< <<<< <<<
- Now let's go back then add 16 for the number of loops we need
- < ++++ ++++ ++++ ++++
- LOOP
- [>
- Move to next part of hash
- >>
- Count down
- [<
- Add 1 to higher digit
- <+>
- Subtract 15 from lower digit
- ----- ----- -----
- If not 0 (original value was not 15) then
- [
- Pull the 1 back off the higher digit
- <->
- Add 16 (total of adding 1)
- ++++ ++++ ++++ ++++
- Shift value from 1 to 18
- [->>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<]
- ]
- Copy from 18 back to 1 just in case above was true (does nothing if it wasn't)
- >>>>>>>>>>>>>>>>>[-<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>]<<<<<<<<<<<<<<<<<
- >-]
- Add 65 (A) to each then print then wipe
- << ++++++++ ++++++++ ++++++++ ++++++++ ++++++++ ++++++++ ++++++++ ++++++++ + . [-]
- > ++++++++ ++++++++ ++++++++ ++++++++ ++++++++ ++++++++ ++++++++ ++++++++ + . [-]
- Now pull hash toward us (this will need repeated 15 times)
- >
- >[-<+>]
- >[-<+>]
- >[-<+>]
- >[-<+>]
- >[-<+>]
- >[-<+>]
- >[-<+>]
- >[-<+>]
- >[-<+>]
- >[-<+>]
- >[-<+>]
- >[-<+>]
- >[-<+>]
- >[-<+>]
- >[-<+>]
- Go back where we were before
- <<<< <<<< <<<< <<<<
- Then one more
- <
- And let loop continue
- <-]
- ]]
- CONS_Printf(player, bf_adv(bf_process(code), input))
- end)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement