[목차] == 개요 == Brain[[fuck]] ~~뇌병신~~ '''대표적인 [[난해한 프로그래밍 언어]].''' 1993년 우어반 뮐러가 제작했으며 제작된 파일 [[확장자]]는 .b/.bf. 개발 목적은 가장 작은 컴파일러로 구현할 수 있는 튜링 완전[* 어떤 프로그래밍 언어나 추상 기계가 튜링 기계와 동일한 계산 능력을 가진다는 뜻이다. 튜링 기계는 계산 가능한 모든 함수를 계산할 수 있는 추상적 모델을 말하는데, 쉽게 말해서 이상적인 [[컴퓨터]]를 생각하면 된다. 한 가지 태클이 걸릴 점은, 현실 역사에선 튜링 기계란 개념이 나온 뒤에 그 개념에 기초해서 컴퓨터가 나왔다는 것.] [[프로그래밍 언어]]를 만드는 것이었다고 한다. '''세상에서 가장 단순하면서 복잡한 언어'''라는 말이 어울리는 언어로, 프로그래밍에 사용되는 문자는 {{{+-][><,.}}} 로 딱 8개다. 프로그래밍 방법은 엄청나게 난해하지만, 일단 튜링 완전 타입의 언어이기 때문에 이론적으로는 컴퓨터가 할 수 있는 모든 일을 다 할 수 있다. 그리고 컴퓨터의 연산이 작동하는 방법을 이해하고 있다면, "배우는" 것은 매우 쉽고 단순하다. 실제로 사용하기가 매우 난해한 게 문제다. 일단은 일반적인 난해한 프로그래밍 언어들이 다 그렇듯이 [[포인터#s-3]]를 기본으로 한 명령 체계를 사용하고 있으며 명령어들 역시 포인터를 옮기는 명령어들로 구성되어 있다. 참고로 이름인 브레인[[퍽]]의 퍽은... 이 글을 보는 사람들이 생각하는 그 퍽이 맞다. Brainfuck이다. 말 그대로 보는 사람의 [[뇌]]를 과부하로 조지려고 만든 [[변태]] 프로그래밍 언어다. 그래서 욕설 필터에 걸리는 경우가 있기 때문에 Brainf*** , 또는 약자만 따서 B.F. 등으로 부르는 경우가 많다고 한다. == 명령어 == * {{{>}}} : 포인터 증가 * {{{<}}} : 포인터 감소 * {{{+}}} : 포인터가 가리키는 바이트의 값을 증가 * {{{-}}} : 포인터가 가리키는 바이트의 값을 감소 * {{{.}}} : 포인터가 가리키는 바이트 값을 [[아스키 코드]] 문자로 출력한다. * {{{,}}} : 포인터가 가리키는 바이트에 아스키 코드 값을 입력한다. 쉽게 말해서 입력 받는 역할이다. * {{{[}}} : 포인터가 가리키는 바이트의 값이 0이 되면 짝이 되는 ]로 이동한다. 의사코드로는 {{{while(*ptr != 0) {...} }}}이다. * {{{]}}} : 포인터가 가리키는 바이트의 값이 0이 아니면 짝이 되는 [로 이동한다. 이외에 공백, 엔터 등 기타 문자는 모두 처리되지 않는다.[* 이 덕분에 별도의 주석 명령어 없이 그냥 평문을 써도 주석이 되는 셈이다.] == 메모리 구조 == 1바이트 정수(char)로 이루어진 32768개의 배열과 포인터 하나가 메모리의 전부. 따라서 총 메모리 공간은 32KB + 4B이다. 물론 인터프린터의 구현체별로 당연히 차이가 있다. 한 자바 구현체의 경우는 65535개의 포인터가 있는 대신 4바이트가 아닌 1바이트로 처리한다. == 예제 == === [[Hello, world!]] === {{{ ++++++++++ [>+++++++>++++++++++>+++>+<<<<-] >++.>+.+++++++..+++.>++++++++++++++.------------.<<+++++++++++++++.>.+++.------.--------.>+. }}} ==== 해설 ==== 이 문단에서는 위 프로그램이 어떻게 동작하여 {{{Hello, World!}}}를 출력하는지를 설명한다. 포인터는 처음에 0번 주소를 가리키고 있으며, 모든 메모리의 초기값은 0임을 잊지 말자. 가독성을 위하여 필요한 부분에는 띄어쓰기를 하였다. 그 전에 잠깐 포인터에 대한 설명을 하자면, 포인터는 메모리의 주소를 가리키는 역할을 한다. '''포인터가 가리키는 주소'''와 '''실제 그 주소의 값'''은 별개의 값으로 취급해야 함을 명심하자. 예를 들어 포인터가 5번 주소를 가리키고 있다면, 5번 주소의 값은 123 이런식이다. 1. '''{{{+++++ +++++}}}''' 포인터가 가리키는 주소(0)의 값을 10 증가시켰다. 메모리의 초기값은 0이므로, 최종적으로 포인터가 가리키는 값에 10이 들어간다. 1. '''{{{[>+++++ ++ >+++++ +++++ >+++ >+ <<<<}}}''' 포인터가 가리키는 주소(0)를 하나씩 증가시키며( > (1) > (2) > (3) > (4) ) 각 주소의 값을 7, 10, 3, 1씩 증가시킨다. 이후 다시 포인터가 가리키는 주소를 0으로 감소시킨다. 1. '''{{{-]}}}''' 포인터가 가리키는 주소(0)의 값을 1 감소시킨 후, 그 값이 0이 아닐 경우 2.의 {{{[}}} 로 돌아간다. 즉 10회 루프문이 되며, 메모리의 1~4번째 주소에는 각각 70, 100, 30, 10의 값이 들어가게 된다. 1. '''{{{>++ .}}}''' → {{{H}}} 포인터가 가리키는 주소를 1 증가시키고(1), 주소의 값(=70)에 2를 더한 후(=72) 그 값을 아스키 코드로 출력한다. 72에 대응되는 아스키 코드 문자는 {{{H}}}이다. 1. '''{{{>+ . +++++ ++ .. +++ .}}}''' → {{{ello}}} 포인터가 가리키는 주소를 1 증가시키고(2), 주소의 값(=100)에 1을 더한 후(=101) 한 번 출력, 7을 더한 후(=108) 두 번 출력, 또다시 3을 더한 후(=111) 한 번 출력한다. 101, 108, 108, 111에 대응되는 아스키 코드 문자는 {{{ello}}}이다. 1. '''{{{>++++++++++++++.------------.<<+++++++++++++++.>.+++.------.--------.>+.}}}''' → {{{, World!}}} 4~5와 같다. 포인터가 가리키는 주소를 이리저리 바꾸고 그 주소의 값에 숫자를 더하고 빼 가면서 문자를 출력한다. 여기서 {{{, World!}}}가 출력되는 것. === [[Hello, world!]] 노가다 출력 === 위와는 다르게 이런 식으로 +를 도배해도 출력이 가능하다.--아니 왜 이러고 사십니까?-- {{{ [-] H ++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++ ++ . [-] e ++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++ + . [-] l 2 >++ [< ++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++. [-] >-]< o ++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++ +. [-] ++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++. [-] Space ++++++++++ ++++++++++ ++++++++++ ++. [-] w ++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++ +++++++++. [-] o ++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++ +. [-] r ++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++. [-] l ++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++. [-] d ++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++. [-] ! ++++++++++ ++++++++++ ++++++++++ +++. [-] Lf ++++++++++ +++. [-] }}} == 기타 == * 놀랍게도 업그레이드(?) 버전으로 2개의 포인터를 쓰는 더블퍽(Doublefuck)--쌍뻐큐--이라는 놈이 존재하며, 같은 원리의 프로그래밍 언어로 [[Ook!]]가 존재한다. Ook!는 브레인퍽과 명령체계가 완전히 똑같아서 브레인퍽-Ook! 컨버전 프로그램도 존재한다. 이외에도 많은 브레인퍽 기반의 esolang이 존재한다. 자세한 내용은 [[난해한 프로그래밍 언어]] 문서의 [[미사쿠라 난코츠|Misa]] 및 [[기어와라! 냐루코양|Nyaruko]] 참조. 그 외에도 일본에는 [[죠죠러]]를 위한 [[http://d.hatena.ne.jp/toyoshi/20100208/1265587511|해당 언어 기반의 esolang]], [[케모노 프렌즈]] 팬덤을 위한 [[http://gall.dcinside.com/mgallery/board/view/?id=kemono&no=145082&page=1|해당 언어 기반의 esolang]]도 존재한다. 최근에는 아예 [[그루트|요 녀석]]에서 따온 [[https://github.com/thiagopnts/groot|언어]]도 등장했다. * [[SeeU]]의 [[반도의 흔한 이별노래]]는 가사 전체가 하나의 브레인퍽 코드로 되어 있다. * [[http://esoteric.sange.fi/brainfuck/impl/interp/i.html|여기]]서 브레인퍽 프로그램을 실행할 수 있다. 여기서는 {{{#}}}가 중단점으로 사용된다. * 한 양덕은 '''[[마인크래프트/레드스톤|마인크래프트의 레드스톤]]으로 [[https://www.youtube.com/watch?v=fZzcYkgkQ-I|브레인퍽 컴퓨터]]를 구현했다'''. 이외에도 찾아보면 마인크래프트로 브레인퍽 인터프리터 구현작업영상들이 좀 있다. * 언어 자체가 매우 간단하여 구현이 쉽다. --언어 기반 언어-- * [[조혜련과 태보의 저주]] 동영상의 자막에는 브레인퍽 자막도 있다(...) [[분류:프로그래밍 언어]][[분류:난해한 프로그래밍 언어]]