Created
July 9, 2019 10:39
-
-
Save Taneb/be9d6d5048ce6ca3c5563df223052c6b to your computer and use it in GitHub Desktop.
brainfuck interpreter in jq
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # invoke as jq -f bf.jq -rS --arg program [PROGRAM] - | |
| # interactivity is not supported | |
| # try: | |
| # $ echo "" | jq -f bf.jq -RrS --arg program '++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.' | |
| def increment: .tape.head+=1; | |
| def decrement: .tape.head-=1; | |
| def shiftleft: | |
| .tape.left=[.tape.head]+.tape.left | | |
| .tape.head=(.tape.right[0]//0) | | |
| .tape.right|=.[1:]; | |
| def shiftright: | |
| .tape.right=[.tape.head]+.tape.right | | |
| .tape.head=(.tape.left[0]//0) | | |
| .tape.left|=.[1:]; | |
| def loop(f): | |
| until(.tape.head == 0; f); | |
| def bfin: | |
| .tape.head=(.in[0]//0) | | |
| .in|=.[1:]; | |
| def bfout: | |
| .out=.out+[.tape.head]; | |
| def setup: | |
| {"tape": | |
| {"left":[] | |
| ,"head":0 | |
| ,"right":[] | |
| } | |
| ,"in":explode | |
| ,"out":[] | |
| }; | |
| def finalize: .out|implode; | |
| def instrs: | |
| {"+": increment | |
| ,"-": decrement | |
| ,"<": shiftleft | |
| ,">": shiftright | |
| ,",": bfin | |
| ,".": bfout | |
| }; | |
| # find the index of closing bracket | |
| def findmatch(prog;d;n): | |
| if prog[n:n+1] == "[" | |
| then findmatch(prog;d+1;n+1) | |
| elif prog[n:n+1] == "]" | |
| then if d == 0 | |
| then n | |
| else findmatch(prog;d-1;n+1) | |
| end | |
| else findmatch(prog;d;n+1) | |
| end; | |
| def interpret(prog): | |
| if prog == "" | |
| then . | |
| elif prog[0:1] == "[" | |
| then findmatch(prog;0;1) as $loopend | loop(interpret(prog[1:$loopend])) | interpret(prog[$loopend+1:]) | |
| else (instrs[(prog[0:1])//.])|interpret(prog[1:]) | |
| end; | |
| setup|interpret($program)|finalize |
Author
@tst2005 I talked to you about this on IRC but for people reading here: your suggestion breaks brainfuck programs which take input, for example ,[.,] (which just emits its input with no further processing).
@Taneb you are right I just forgot that BrainFuck is able to be use as a real program to process data, no just to obfuscate a secret string like "hello world". ;-)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
To be able to use
cat helloworld.bf | jq -f bf.jq -RrS