Skip to content

Instantly share code, notes, and snippets.

@TOTBWF
Last active September 25, 2017 20:09
Show Gist options
  • Save TOTBWF/55cefbddeb36e85da45582ed25d2bf1c to your computer and use it in GitHub Desktop.
Save TOTBWF/55cefbddeb36e85da45582ed25d2bf1c to your computer and use it in GitHub Desktop.
BrainFuck in Prolog
:- set_prolog_flag(double_quotes, chars).
tape(N, List) :- length(List, N), zeros(List).
zeros([]).
zeros([0|T]) :- zeros(T).
interpret(_, [], _, _, _, Acc) --> { reverse(Acc, RAcc) }, RAcc.
interpret(Seen, [+|Next], Left, [Data], Right, Acc) --> { NData is Data + 1}, interpret([+|Seen], Next, Left, [NData], Right, Acc).
interpret(Seen, [-|Next], Left, [Data], Right, Acc) --> { NData is Data - 1}, interpret([-|Seen], Next, Left, [NData], Right, Acc).
interpret(Seen, [<|Next], [H|Left], [Data], Right, Acc) --> interpret([<|Seen], Next, Left, [H], [Data|Right], Acc).
interpret(Seen, [>|Next], Left, [Data], [H|Right], Acc) --> interpret([>|Seen], Next, [Data|Left], [H], Right, Acc).
interpret(Seen, [.|Next], Left, [Data], Right, Acc) --> interpret([.|Seen], Next, Left, [Data], Right, [Data|Acc]).
interpret(Seen, ['['|Next], Left, [0], Right, Acc) --> {jmp_fwd(['['|Seen], Next, 0, NSeen, NNext)}, interpret(NSeen, NNext, Left, [0], Right, Acc).
interpret(Seen, ['['|Next], Left, [Data], Right, Acc) --> interpret(['['|Seen], Next, Left, [Data], Right, Acc).
interpret(Seen, [']'|Next], Left, [0], Right, Acc) --> interpret([']'|Seen], Next, Left, [0], Right, Acc).
interpret(Seen, [']'|Next], Left, [Data], Right, Acc) --> {jmp_bwd([']'|Seen], Next, -1, NSeen, NNext)}, interpret(NSeen, NNext, Left, [Data], Right, Acc).
jmp_fwd(Seen, [']'|Next], 0, [']'|Seen], Next).
jmp_fwd(Seen, [']'|Next], Brackets, SeenOut, NextOut) :- NBrackets is Brackets - 1, jmp_fwd([']'|Seen], Next, NBrackets, SeenOut, NextOut).
jmp_fwd(Seen, ['['|Next], Brackets, SeenOut, NextOut) :- NBrackets is Brackets + 1, jmp_fwd(['['|Seen], Next, NBrackets, SeenOut, NextOut).
jmp_fwd(Seen, [I|Next], Brackets, SeenOut, NextOut) :- jmp_fwd([I|Seen], Next, Brackets, SeenOut, NextOut).
jmp_bwd(['['|Seen], Next, 0, ['['|Seen], Next).
jmp_bwd(['['|Seen], Next, Brackets, SeenOut, NextOut) :- NBrackets is Brackets - 1, jmp_bwd(Seen, ['['|Next], NBrackets, SeenOut, NextOut).
jmp_bwd([']'|Seen], Next, Brackets, SeenOut, NextOut) :- NBrackets is Brackets + 1, jmp_bwd(Seen, [']'|Next], NBrackets, SeenOut, NextOut).
jmp_bwd([I|Seen], Next, Brackets, SeenOut, NextOut) :- jmp_bwd(Seen, [I|Next], Brackets, SeenOut, NextOut).
run(Prog, Output) :- tape(1000, [Data|Tape]), length(Prog, _), phrase(interpret([], Prog, [], [Data], Tape, []), Output).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment