BrainFuck

 

1. 개요
2. 명령어
3. 메모리 구조
4. 예제
4.1.1. 해설
4.2. Hello, world! 노가다 출력
5. 기타


1. 개요


Brainfuck
'''대표적인 난해한 프로그래밍 언어.''' 1993년 우어반 뮐러가 제작했으며 제작된 파일 확장자는 .b/.bf.
개발 목적은 가장 작은 컴파일러로 구현할 수 있는 튜링 완전[1] 프로그래밍 언어를 만드는 것이었다고 한다. '''세상에서 가장 단순하면서 복잡한 언어'''라는 말이 어울리는 언어로, 프로그래밍에 사용되는 문자는
+-][><,.
로 딱 8개다.
프로그래밍 방법은 엄청나게 난해하지만, 일단 튜링 완전 타입의 언어이기 때문에 이론적으로는 컴퓨터가 할 수 있는 모든 일을 다 할 수 있다. 그리고 컴퓨터의 연산이 작동하는 방법을 이해하고 있다면, "배우는" 것은 매우 쉽고 단순하다. 실제로 사용하기가 매우 난해한 게 문제다. 일단은 일반적인 난해한 프로그래밍 언어들이 다 그렇듯이 포인터#s-3를 기본으로 한 명령 체계를 사용하고 있으며 명령어들 역시 포인터를 옮기는 명령어들로 구성되어 있다.
참고로 이름인 브레인의 퍽은... 이 글을 보는 사람들이 생각하는 그 퍽이 맞다. Brainfuck이다. 말 그대로 보는 사람의 를 과부하로 조지려고 만든 변태 프로그래밍 언어다. 그래서 욕설 필터에 걸리는 경우가 있기 때문에 Brainf*** , 또는 약자만 따서 B.F. 등으로 부르는 경우가 많다고 한다.

2. 명령어


  • >
    : 포인터 증가
  • <
    : 포인터 감소
  • +
    : 포인터가 가리키는 바이트의 값을 증가
  • -
    : 포인터가 가리키는 바이트의 값을 감소
  • .
    : 포인터가 가리키는 바이트 값을 아스키 코드 문자로 출력한다.
  • ,
    : 포인터가 가리키는 바이트에 아스키 코드 값을 입력한다. 쉽게 말해서 입력 받는 역할이다.
  • [
    : 포인터가 가리키는 바이트의 값이 0이 되면 짝이 되는 ]로 이동한다. 의사코드로는
    while(*ptr != 0) {...}
    이다.
  • ]
    : 포인터가 가리키는 바이트의 값이 0이 아니면 짝이 되는 [로 이동한다.
이외에 공백, 엔터 등 기타 문자는 모두 처리되지 않는다.[2]

3. 메모리 구조


1바이트 정수(char)로 이루어진 32768개의 배열과 포인터 하나가 메모리의 전부.
따라서 총 메모리 공간은 32KB + 4B이다.
물론 인터프린터의 구현체별로 당연히 차이가 있다. 한 자바 구현체의 경우는 65535개의 포인터가 있는 대신 4바이트가 아닌 1바이트로 처리한다.

4. 예제



4.1. Hello, world!


++++++++++
[>+++++++>++++++++++>+++>+<<<<-]
>++.>+.+++++++..+++.>++++++++++++++.------------.<<+++++++++++++++.>.+++.------.--------.>+.

4.1.1. 해설


이 문단에서는 위 프로그램이 어떻게 동작하여
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!
가 출력되는 것.

4.2. Hello, world! 노가다 출력


위와는 다르게 이런 식으로 +를 도배해도 출력이 가능하다.
[-] H
++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++
++++++++++ ++++++++++ ++ .
[-] e
++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++
++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++ + .
[-] l 2
>++
[<
++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++
++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++
++++++++.
[-]
>-]< o
++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++
++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++
++++++++++ +.
[-]
++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++.
[-] Space
++++++++++ ++++++++++ ++++++++++ ++.
[-] w
++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++
++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++
++++++++++ +++++++++.
[-] o
++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++
++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++
++++++++++ +.
[-] r
++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++
++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++
++++++++++ ++++.
[-] l
++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++
++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++
++++++++.
[-] d
++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++
++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++.
[-] !
++++++++++ ++++++++++ ++++++++++ +++.
[-] Lf
++++++++++ +++.
[-]

5. 기타


  • 놀랍게도 업그레이드(?) 버전으로 2개의 포인터를 쓰는 더블퍽(Doublefuck) 이라는 놈이 존재하며, 같은 원리의 프로그래밍 언어로 Ook!가 존재한다. Ook!는 브레인퍽과 명령체계가 완전히 똑같아서 브레인퍽-Ook! 컨버전 프로그램도 존재한다.
이외에도 많은 브레인퍽 기반의 esolang이 존재한다. 자세한 내용은 난해한 프로그래밍 언어 문서의 MisaNyaruko 참조. 그 외에도 일본에는 죠죠러를 위한 해당 언어 기반의 esolang, 케모노 프렌즈 팬덤을 위한 해당 언어 기반의 esolang도 존재한다. 최근에는 아예 요 녀석에서 따온 언어도 등장했다.
  • 여기서 브레인퍽 프로그램을 실행할 수 있다. 여기서는
    #
    가 중단점으로 사용된다.
  • 언어 자체가 매우 간단하여 구현이 쉽다.

[1] 어떤 프로그래밍 언어나 추상 기계가 튜링 기계와 동일한 계산 능력을 가진다는 뜻이다. 튜링 기계는 계산 가능한 모든 함수를 계산할 수 있는 추상적 모델을 말하는데, 쉽게 말해서 이상적인 컴퓨터를 생각하면 된다. 한 가지 태클이 걸릴 점은, 현실 역사에선 튜링 기계란 개념이 나온 뒤에 그 개념에 기초해서 컴퓨터가 나왔다는 것.[2] 이 덕분에 별도의 주석 명령어 없이 그냥 평문을 써도 주석이 되는 셈이다.