Skip to content

Instantly share code, notes, and snippets.

@xnuk
Last active September 5, 2019 22:42
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save xnuk/1f6f65ce001c49703cdd to your computer and use it in GitHub Desktop.
Save xnuk/1f6f65ce001c49703cdd to your computer and use it in GitHub Desktop.

아희 유형 A 프로그래밍 언어 설명 문서 - draft 버전 1.2.0

한국어

한국어는 애매합니다. 정확히는 명료한 언어 설명 문서를 적기에는 부족한 점이 좀 있습니다. 따라서, 본론에 들어가기 전 몇 가지 표현을 미리 명료히 하겠습니다.

  • A에서 B까지 / A부터 B까지: A와 B 사이에 있는 구간에서 A와 B를 포함한 구간을 칭합니다.
  • (U+AC00) 이상 (U+D7A3) 이하: 유니코드의 문자 번호가 십육진수 표기로 AC00 이상 D7A3 이하에 속하는 모든 유니코드 문자를 칭합니다.
  • 이 문서에서의 숫자 표기는 별도로 정의하지 않는 이상 십진수 표기를 사용합니다.
    • U+AC00U+ 뒤에 바로 따라 나오는 네 자리 문자는 십육진수 표기를 사용합니다.
  • 받침종성은 동의어로 봅니다.
  • 모음중성은 동의어로 봅니다.

언어의 명칭

이 언어는 이 언어를 부르는 명칭이 아직 정해지지 않았으며, 편의상 아희(가칭)라고 부릅니다.

코드의 정의

  • 이 문서에서의 "아희 코드"라 함은 0개 이상의 유니코드 문자들을 순서 있게 나열한 문자열을 뜻합니다. 모든 유니코드 문자의 나열은 실행 가능한 프로그램으로 만들 수 있는 아희 코드가 됩니다.
  • 유니코드 문자가 아닌 문자가 포함된 코드는 아희 코드가 아닙니다. 코드에 그런 문자가 포함되었을 경우 이 문서는 해당 코드를 실행하거나 실행 가능한 상태로 만드는 구현체에 대해 어떠한 행동도 지시하거나 보장할 수 없습니다.
  • 이 문서에서 "코드"라 함은 별다른 얘기가 없는 한 "아희 코드"를 지칭합니다.

줄바꿈

코드를 줄바꿈 문자 기준으로 나누어 나오는 문자열들을 각각 "행"(row)이라고 칭합니다. 한 행에 있는 문자열은 빈 문자열일 수도 있습니다. 여기에서의 줄바꿈 문자는 다음 표와 같습니다. 단, CARRIAGE RETURN(U+000D) 한 문자와 연속해서 나오는 LINE FEED(U+000A) 한 문자 이 두 문자는 줄바꿈 문자 두 문자가 아닌 줄바꿈 문자 한 문자로 인식합니다.

코드 포인트 유니코드 명칭
U+000A LINE FEED
U+000D CARRIAGE RETURN
U+2028 LINE SEPARATOR
U+2029 PARAGRAPH SEPARATOR

공백 문자

이 문서에서 공백 문자라 함은 "Separator, space" (Zs) 카테고리에 속한 유니코드 문자 또는 다음 표에 속한 문자를 뜻합니다.

코드 포인트 유니코드 명칭
U+0009 CHARACTER TABULATION
U+000B LINE TABULATION
U+000C FORM FEED (FF)
U+0020 SPACE
U+00A0 NO-BREAK SPACE
U+FEFF ZERO WIDTH NO-BREAK SPACE

언어 확장

아희는 언어에 기능을 덧붙이거나 언어를 색다르게 해석할 수 있는 언어 확장을 지원합니다. 언어 확장을 하도록 코드 또는 외부 옵션으로 설정이 가능토록 하는 것을 "언어 확장 플래그"라 부릅니다. 이 문서에서 정의하지 않은 언어 확장 플래그 및 그에 대한 동작은 구현체마다 새로 추가가 가능하며, 기본적으로 비활성화되어 있어야 합니다. 이 문서는 이 문서에서 정의하지 않은 언어 확장 플래그를 활성화시켰을 경우에 대한 구현체의 동작을 보장하지 않습니다.

코드 안에서의 언어 확장 플래그는 맨 처음 행부터 연속되어 나오는 (U+AC00) 이상 (U+D7A3) 이하 구간(이하 이 구간에 속하는 문자를 "한글 음절 문자"라고 지칭합니다.) 안의 문자가 포함되지 않은 행들에서 찾습니다. 다르게 말해 한글 음절 문자가 나온 행 이후의 구간에서는 찾지 않습니다. 맨 처음 행에 한글 음절 문자가 나온 경우 코드 내에서 설정한 언어 확장 플래그가 없다고 봅니다. 코드 내에 한글 음절 문자가 존재하지 않는 경우 맨 처음 행부터 맨 마지막 행까지의 구간에서 찾습니다. 구간 내 행 중에서 다음을 만족하는 행들만 취해서 처리합니다. 만족하지 않는 행들은 모두 무시합니다.

  • 문자열이 #:로 시작되어야 합니다.

  • 다음 EBNF를 만족해야 합니다. 여기서 nameA(U+0041) 이상 Z(U+005A) 이하 또는 _(U+005F)에 해당되는 문자들로만 구성된 문자열을 뜻합니다. 또 여기서 whitespace의 정의는 공백 문자에 정의된 문자들로만 구성된 문자열을 뜻합니다.

    row = "#:", [ whitespace ], name, [ whitespace, name ], [ whitespace ];

위 EBNF에서 첫 번째 name을 "플래그"라 부르고, 두 번째 name을 "값"이라고 부르겠습니다. 플래그가 있으나 값이 없으면 값은 SET으로 설정되었다고 봅니다. 각각의 플래그에는 값이 설정되어 있으며, 별도로 정의하지 않은 경우 플래그 각각의 기본값으로 설정합니다. 나중에 설정된 플래그가 먼저 설정된 같은 플래그를 덮어 씁니다.

플래그별 설명

이 플래그들은 이 스펙에서 예약되었습니다. 다음은 플래그의 기본값 및 특징입니다. 플래그가 가질 수 없는 값이 설정되었을 경우 해당 플래그의 값을 기본값으로 변경합니다.

  • CONDITIONAL_CANNON_JUMP: 값은 SET 또는 UNSET을 갖습니다. 기본값은 UNSET입니다.
  • CANNON_JUMP: 값은 SET 또는 UNSET을 갖습니다. 기본값은 UNSET입니다.
  • NEED_MORE_COPY: 값은 SET 또는 UNSET을 갖습니다. 기본값은 UNSET입니다.
  • DEEP_EXCHANGE: 값은 SET 또는 UNSET을 갖습니다. 기본값은 UNSET입니다.
  • CALC_BY_BATCHIM: 값은 SET 또는 UNSET을 갖습니다. 기본값은 UNSET입니다.
  • OVERWRITE_REDEFINED_BATCHIMS: 값은 SET 또는 UNSET을 갖습니다. 기본값은 UNSET입니다.
  • INPUT_WHITESPACE_IGNORE_LEVEL: 값은 ALL, WHITESPACE, LINE_BREAK, DO_NOT_IGNORE 중 하나를 갖습니다. 기본값은 ALL입니다.
  • PASSAGE_SPEC: SET 을 제외한 구현체가 지원할 수 있는 통로 설명 문서의 이름값을 가질 수 있습니다. 기본값은 NULL입니다.

명령어 구역

아희 코드에는 프로그램을 실행하는 데 필요한 실질적인 명령어들을 2차원으로 나열한 구역이 있습니다. 이를 "명령어 구역"이라 부르고, 이 명령어 구역은 다음과 같이 정의됩니다: 코드 내에서 한글 음절 문자가 포함된 맨 처음 행에서 한글 음절 문자가 포함된 맨 마지막 행까지의 코드 내에서의 구역. 코드 내에 한글 음절 문자가 존재하지 않는 경우 명령어 구역은 없다고 봅니다. 또한 편의상 이 문서에서는 다음과 같은 표기가 사용됩니다.

  • 명령어 구역의 n 번째 행의 m 번째 문자에 해당하는 위치를 (n-1, m-1)이라고 부릅니다. 예를 들어 첫 번째 행의 두 번째 문자의 위치는 (0, 1)입니다.
  • 명령어 구역의 모든 행들의 n 번째 위치로 구성된 것을 n 번째 "열"이라고 부릅니다. 먼저 나온 행의 위치일 수록 위에 있는 위치라고 칭합니다.

기타 행

언어 확장 플래그 선언과 명령어 구역 이외의 행들은 모두 무시합니다.

빈 코드

언어 확장 플래그가 하나도 선언되어 있지 않고(외부에서 언어 확장 플래그를 설정했고 구현체에서 그 플래그를 코드에 적용시키는 경우에도 "언어 확장 플래그를 선언했다"고 봅니다.) 명령어 구역이 없을 경우, 이것을 "코드가 비었다"고 보며, 프로그램은 이 코드를 "언어 확장 플래그가 없고 명령어 구역이 한 행밖에 없으며 그 행의 첫 문자가 인 코드"로 취급합니다. 언어 확장 플래그가 있지만 명령어 구역이 없을 경우, 빈 코드에서 언어 확장 플래그가 적용되었다고 봅니다.

명령어 구역 내의 명령어 해석 및 실행

명령어 구역은 줄바꿈 문자가 아닌 유니코드 문자들이 담긴 행들의 집합으로 이루어져 있습니다. 아희는 (0, 0)의 문자부터 시작하여 문자를 해석하고 해당하는 명령어를 실행하고 다음에 해석할 문자의 위치를 정하는 방식으로 실행되는 언어입니다.

글자

한글 음절 문자가 아닌 모든 문자는 현재 실행 상태의 "속도"를 유지시키는 일 외에 아무 일도 하지 않습니다. "속도"는 "진행 방향"과 "이동 거리"로 구성되어 있으며, 자세한 내용은 속도에서 서술합니다.

한글 음절 문자는 초성, 중성, 종성에 따라 나눌 수 있습니다. 어떤 한 한글 음절 문자의 유니코드 값에서 초성, 중성, 종성에 해당하는 글자를 알아내는 방법은 다음과 같습니다. 이 과정에서의 나눗셈의 몫은 항상 음수가 아닌 정수이며 나머지는 항상 제수보다 작고 0보다 크거나 같은 정수가 됩니다.

  1. 유니코드 값에서 44032((U+AC00)에 해당하는 값입니다)를 뺀 값을 x라고 합니다.
  2. x28로 나누어 나온 몫을 y라고 하고, 나머지는 종성에 해당하는 값이 됩니다.
  3. y21로 나누어 나온 몫은 초성에 해당하는 값이 되고, 나머지는 중성에 해당하는 값이 될니다.
  4. 초성, 중성, 종성에 해당하는 값에 대응하는 글자는 다음 표와 같습니다.
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
초성
중성
종성 (없음)

속도

아희는 다음에 해석할 문자의 위치를 파악하는 데 필요한 "속도"를 가지고 있습니다. 속도는 "진행 방향"과 "이동 거리"로 구성되어 있습니다. 진행 방향은 , , , 중 하나의 값을 가지며, 이동 거리는 0보다 큰 자연수 값을 가지며 이 값은 16보다 클 수 없습니다. 속도 중 진행 방향은 한글 음절 문자의 중성에 의해서만 변경될 수 있으며, 이동 거리의 경우 한글 음절 문자의 초성, 중성, 종성에 의해 변경될 수 있습니다. 다음은 한글 음절 문자의 중성과 그에 따른 속도의 변경을 서술합니다. 무엇을 할지 결정되지 않은 중성은 속도를 변경하지 않습니다.

  • : 진행 방향을 로 변경하고 이동 거리를 1로 변경합니다.
  • : 진행 방향을 로 변경하고 이동 거리를 2로 변경합니다.
  • : 진행 방향을 로 변경하고 이동 거리를 1로 변경합니다.
  • : 진행 방향을 로 변경하고 이동 거리를 2로 변경합니다.
  • : 진행 방향을 로 변경하고 이동 거리를 1로 변경합니다.
  • : 진행 방향을 로 변경하고 이동 거리를 2로 변경합니다.
  • : 진행 방향을 로 변경하고 이동 거리를 1로 변경합니다.
  • : 진행 방향을 로 변경하고 이동 거리를 2로 변경합니다.
  • : 진행 방향이 일 경우 로, 일 경우 으로 변경합니다. 그밖의 경우 진행 방향을 변경하지 않습니다. 이동 거리는 변경하지 않습니다.
  • : 진행 방향이 일 경우 로, 일 경우 로 변경합니다. 그밖의 경우 진행 방향을 변경하지 않습니다. 이동 거리는 변경하지 않습니다.
  • : 진행 방향이 일 경우 로, 일 경우 로, 일 경우 로, 일 경우 으로 변경합니다. 이동 거리는 변경하지 않습니다. (이하 이 동작을 "진행 방향을 뒤집다"라는 표현으로 칭하겠습니다.)

속도는 먼저 한글 음절 문자의 중성에 의해 변경됩니다. 그 후 같은 글자의 초성이 가리키는 명령에 따라 변경될 수 있습니다. 중성과 초성에 의해 속도가 변경되기 전에 속도가 결정되지 않은 경우 다음과 같은 행동을 합니다.

  • 진행 방향이 결정되지 않은 경우 진행 방향을 로 설정합니다.
  • 이동 거리가 결정되지 않은 경우 이동 거리를 1로 설정합니다.

초성이 가리키는 명령의 수행이 끝났을 경우 프로그램은 다음에 해석할 글자의 위치로 이동하여 글자를 해석해야 합니다. 그 위치는 현재 글자의 위치와 초성이 가리키는 명령이 수행된 후 결정된 속도에 의해 결정됩니다. 현재 글자의 위치를 (r, c)라고 하고, 속도의 이동 거리를 d라고 할 때 다음에 해석할 글자의 위치는 다음과 같이 계산됩니다.

  • 진행 방향이 일 경우
    1. cd보다 작은 경우, 다음에 이동할 위치는 현재 행의 가장 마지막 글자가 됩니다.
    2. 그렇지 않은 경우, 다음에 이동할 위치는 (r, c-d)가 됩니다.
  • 진행 방향이 일 경우
    1. (r, c+d)에 해당하는 글자가 없는 경우, 다음에 이동할 위치는 현재 행의 가장 첫 글자가 됩니다.
    2. 그렇지 않은 경우, 다음에 이동할 위치는 (r, c+d)가 됩니다.
  • 진행 방향이 일 결우
    1. rd보다 작은 경우, 명령어 구역 내 맨 마지막 행을 s+1번째 행이라고 볼 때, 다음에 이동할 위치는 (s, c)가 됩니다.
    2. 그렇지 않은 경우, 다음에 이동할 위치는 (r-d, c)가 됩니다.
    3. 1., 2.에 의해 결정된 위치에 해당하는 문자가 없을 경우, 글자 해석 과정에서 해당 위치엔 한글 음절 문자가 아닌 문자가 있다고 가정하고 과정을 진행합니다. 이 가정은 진행 방향이 이거나 인 경우에는 적용되지 않는 가정임에 유의하시기 바랍니다.
  • 진행 방향이 일 결우
    1. 마지막 행을 s+1번째 행이라고 볼 때, r+ds보다 큰 경우, 다음에 이동할 위치는 (0, c)가 됩니다.
    2. 그렇지 않은 경우, 다음에 이동할 위치는 (r+d, c)가 됩니다.
    3. 1., 2.에 의해 결정된 위치에 해당하는 문자가 없을 경우, 글자 해석 과정에서 해당 위치엔 한글 음절 문자가 아닌 문자가 있다고 가정하고 과정을 진행합니다. 이 가정은 진행 방향이 이거나 인 경우에는 적용되지 않는 가정임에 유의하시기 바랍니다.

한글 음절 문자가 아닌 모든 문자는 속도의 변경에 관여할 수 없으며, 이는 해당 문자를 초성, 중성, 종성으로 분해할 수 없기 때문에 일어나는 현상입니다. 이런 문자를 만난 경우 바로 위의 진행 방향에 따른 다음에 해석할 글자 위치 계산 과정을 거쳐 다음에 해석할 글자로 바로 이동합니다.

저장 공간

아희는 26개의 서로 다른 스택과 1개의 큐와 1개의 외부와 소통할 수 있는 통로를 기본적으로 가지고 있는 언어입니다. 큐는 받침에 연결되어 있고, 통로는 받침에 연결되어 있으며, (받침 없음)에 스택이 하나 연결되어 있고, 기본적으로 나머지 받침들에 연결된 저장 공간들은 전부 스택입니다. 프로그램 실행 중에 이 저장 공간들 중 하나만을 가리키는 커서가 있으며, 프로그램 시작 시부터 프로그램이 다른 저장 공간을 가리키기 전까진 기본적으로 (받침 없음) 공간을 가리킵니다.

언어 확장 플래그 또는 통로 안에서의 동작에 의해 (받침 없음), , 을 제외한 나머지 받침에 스택이 아닌 다른 저장 공간이 할당될 수 있습니다. 통로의 동작에 의해 다른 저장 공간이 할당되는 경우 다음 조건을 만족해야 가능합니다.

  • 바꾸려는 받침의 저장공간이 현재 프로그램이 가리키는 저장공간이 아니어야 합니다.
  • 바꾸려는 받침의 저장공간이 비어있어야 합니다.
  • 바꾸려는 받침이 일 경우 위 두 조건을 무시할 수 있습니다.

스택, 큐, 통로에서 들어가거나 나오는 자료형은 모두 정수이며, 구현체는 적어도 231(2147483648) 미만 -231 이상의 정수 구간을 지원해야 합니다. 또한 스택과 큐는 적어도 215(32768)개의 정수를 저장할 수 있어야 합니다.

  • 스택: 먼저 들어간 자료일 수록 나중에 나오는 저장 공간입니다. 명령어에 의해 자료의 위치가 바뀔 수 있습니다.
  • 큐: 먼저 들어간 자료일 수록 먼저 나오는 저장 공간입니다. 명령어에 의해 자료의 위치가 바뀔 수 있습니다.
  • 통로: 외부와 소통할 수 있는 공간입니다. 넣은 자료와 뽑아낸 자료가 일치함을 보장하지 않습니다.
    • PASSAGE_SPEC 플래그가 NULL인 경우, 넣은 자료와 관계없이 뽑아낸 자료는 항상 0이 됩니다.
    • PASSAGE_SPEC 플래그에 설정된 NULL이 아닌 값은 통로의 동작을 정의한 설명 문서의 이름이 되고, 구현체는 이 값에 따른 설명 문서를 대응하고 이에 따라 통로를 구현함을 기대합니다.

초성에 의한 명령어

글자를 해석할 때 속도의 변경 뿐만 아니라 프로그램이 해야 할 일을 지정해줄 수도 있습니다. 이런 명령의 유형 및 동작들은 초성에 따라 결정됩니다. 무슨 명령을 할지 결정되지 않은 초성은 와 같은 동작을 합니다.

참고로 명령 수행 중 오류가 났을 경우 다음과 같이 행동하려는 습성이 있습니다만, 이것이 모든 명령에 대해 항상 그러함을 뜻하지는 않습니다.

  • 뽑아야 할 값의 개수보다 저장 공간에 있는 값의 개수가 더 적을 경우, 속도의 진행 방향을 뒤집고 값은 뽑지 않으려 합니다.
  • 뽑은 값이 특정 조건에 일치하지 않은 경우, 속도의 진행 방향을 뒤집고 필요한 값은 뽑은 것으로 처리하려 합니다.

아무 일도 하지 않습니다.

프로그램을 종료합니다. 이때 종료 코드를 반환하게 되는데, 반환할 종료 코드는 다음과 같이 계산됩니다.

  • 현재 가리키고 있는 저장 공간이 통로인 경우 0을 반환합니다.
  • 현재 가리키고 있는 저장 공간이 스택 또는 큐일 경우:
    • 빈 스택 또는 빈 큐일 경우 0을 반환합니다.
    • 그렇지 않은 경우 저장 공간에서 값을 하나 뽑아 그 값을 반환합니다. 뽑은 값이 운영체제에서 종료 코드로 받아들일 수 없는 정수인 경우에 반환하는 종료 코드의 값은 보장하지 않습니다만, 프로그램의 종료는 이루어져야 합니다.

CANNON_JUMP 플래그가 SET이고 받침이 나타내는 값이 1 이상인 경우, 속도의 이동 거리를 받침이 나타내는 값으로 변경합니다. 받침이 나타내는 값은 ㅇ, ㅎ를 제외한 받침의 정의를 따릅니다. 받침이 ㅇ 또는 ㅎ일 경우 초성이 인 경우와 같은 동작을 합니다.

CANNON_JUMP 플래그가 SET이고 받침이 나타내는 값이 0인 경우, 저장 공간에서 값을 하나 뽑아 그 값을 속도의 이동 거리로 설정합니다. 값을 뽑을 수 없을 경우 속도의 이동 거리를 변화하지 않고 속도의 진행 방향만을 뒤집습니다. 뽑은 값이 0보다 작거나 같을 경우 속도의 이동 거리를 1로 설정합니다. 뽑은 값이 16보다 클 경우 속도의 이동 거리를 16로 설정합니다.

CANNON_JUMP 플래그가 UNSET일 경우 초성이 인 경우와 같은 동작을 합니다.

계산(ㄷ, ㅌ, ㄸ, ㄴ, ㄹ, ㅈ)

ㄷ, ㅌ, ㄸ, ㄴ, ㄹ 전부 현재 저장 공간에서 값을 두 번 뽑는 과정이 선행됩니다. 현재 저장 공간에서 값을 두 번 뽑을 수 없는 경우, 값을 뽑는 과정을 수행하지 않고 속도의 진행 방향을 뒤집은 후 이하의 과정을 생략합니다. 여기선 두 번 뽑은 값 중에 먼저 뽑은 값을 a라고 하고, 나중에 뽑은 값을 b라고 합니다.

  • : ab를 더한 값을 저장 공간에 넣습니다.
  • : b에서 a를 뺀 값을 저장 공간에 넣습니다.
  • : ab를 곱한 값을 저장 공간에 넣습니다.
  • : b를 피제수로 하고 a를 제수로 하는 나눗셈을 하여 나온 몫을 저장 공간에 넣습니다.
  • : b를 피제수로 하고 a를 제수로 하는 나눗셈을 하여 나온 나머지을 저장 공간에 넣습니다.
  • : ba보다 크거나 같으면 1을, 아니면 0을 저장 공간에 넣습니다.

에서 사용되는 나눗셈은 다음의 조건을 만족하는 나눗셈입니다.

  • 몫과 나머지는 항상 정수입니다.
  • 나머지의 절댓값은 제수의 절댓값보다 작습니다.
  • 제수가 음수가 아니면 나머지 역시 음수가 아니고, 제수가 양수가 아니면 나머지 역시 양수가 아닙니다.
  • 제수와 몫을 곱한 값에 나머지를 더한 값은 피제수와 같아야 합니다.

에서 a가 0인 경우, 저장 공간에서 한 번만 뽑은 것으로 처리합니다. 즉 a를 뽑은 것으로 보고 b를 뽑지 않은 것으로 봅니다. 그 후 속도의 진행 방향을 뒤집습니다.

CALC_BY_BATCHIM 플래그가 SET인 경우, 위의 과정은 받침이 없거나 받침이 ㅇ 또는 ㅎ일 경우에만 적용됩니다. 받침이 있는 경우 위의 과정이 다음과 같이 변경되어 적용됩니다:

  • 현재 저장 공간에서 값을 한 번만 뽑고, 그 값은 b로 취급합니다. 현재 저장 공간에서 값을 뽑을 수 없는 경우, 값을 뽑는 과정을 수행하지 않고 속도의 진행 방향을 뒤집은 후 과정을 생략합니다.
  • a는 받침이 나타내는 값이 됩니다. 받침이 나타내는 값은 ㅇ, ㅎ를 제외한 받침의 정의를 따릅니다. 단 이 값은 저장 공간에서 뽑은 값이 아니기 때문에 저장 공간으로는 들어가지 않는다는 점을 유의하시기 바랍니다.
  • 에서 a가 0인 경우, 저장 공간에서 값을 뽑지 않은 것으로 취급합니다. 그 후 속도의 진행 방향을 뒤집습니다.
    • 이 "a가 0인 경우"는 구현체가 정의한 언어 확장 플래그에 의해 접근이 가능할 수 있는 경우이기 때문에, 따로 명시해둡니다.

현재 저장 공간에서 값을 하나 뽑습니다. 값을 뽑을 수 없으면 값을 뽑는 과정을 수행하지 않고 속도의 진행 방향을 뒤집은 후 이하의 과정을 생략합니다. 뽑은 값이 0이면 속도의 진행 방향을 뒤집습니다. 0이 아니면 진행 방향을 변경하지 않습니다. CONDITIONAL_CANNON_JUMP 플래그가 SET이고 받침이 나타내는 값이 3 이상인 경우, 속도의 이동 거리를 받침이 나타내는 값으로 변경합니다. 받침이 나타내는 값은 ㅇ, ㅎ를 제외한 받침의 정의를 따릅니다. 값을 뽑을 수 없는 경우 값을 뽑는 과정을 수행하지 않고 속도의 이동 거리는 받침이 나타내는 값으로 하고, 방향은 뒤집습니다.

현재 저장 공간에서 n번 뽑아냈을 때 가장 나중에 나오는 값의 위치를 n번째 위치라고 하고 1번째 위치에 있는 값을 a라고 할 때, 모든 가능한 n에 대하여 n번째 위치를 n+1번째 위치로 옮긴 후, 1번째 위치의 값을 a로 설정합니다. 즉 1번째 위치와 2번째 위치 모두 a가 되게 합니다. 현재 저장 공간이 스택이거나 큐일 경우에만 적용됩니다. 현재 저장 공간에서 값을 한 번 뽑아낼 수 없으면 이 동작을 실행하지 않고 속도의 진행 방향만 뒤집고 이하의 과정을 생략합니다.

NEED_MORE_COPYSET인 경우, 위의 경우는 받침이 나타내는 값이 2 미만일 경우에만 적용됩니다. 받침이 나타내는 값은 ㅇ, ㅎ를 제외한 받침의 정의를 따릅니다. 2 이상의 경우 다음과 같이 변경되어 적용됩니다: 받침이 나타내는 값을 x라 하고 1번째 위치에 있는 값을 a라고 할 때, 모든 가능한 n에 대하여 n번째 위치를 n+x번째 위치로 옮긴 후, 1번째부터 x번째 위치까지의 값을 a로 설정합니다. 즉 1번째 위치부터 x+1번째 위치까지의 값 모두 a가 되게 합니다.

현재 저장 공간이 통로인 경우 다음을 따릅니다.

  • PASSAGE_SPEC 플래그가 NULL일 경우 ㅇ 명령과 같은 동작을 하게 됩니다.
  • 그렇지 않은 경우 PASSAGE_SPEC 플래그의 값에 해당하는 문서에 서술된 ㅃ의 동작을 하며, 또한 이 문서는 해당 문서가 ㅃ의 동작을 서술할 것을 기대합니다.

현재 저장 공간에서 n번 뽑아냈을 때 가장 나중에 나오는 값의 위치를 n번째 위치라고 할 때, 1번째 위치와 2번째 위치에 있는 값을 서로 맞바꿉니다. 실제로 뽑기 명령은 수행되지 않습니다. 현재 저장 공간이 스택이거나 큐일 경우에만 적용됩니다. 저장 공간에서 값을 두 번 뽑아낼 수 없으면 맞바꾸지 않고 속도의 진행 방향만 뒤집습니다.

DEEP_EXCHANGE 플래그가 SET인 경우, 위의 과정은 받침이 나타내는 값이 0보다 크지 않은 경우에만 적용됩니다. 받침이 나타내는 값의 정의는 ㅇ, ㅎ를 제외한 받침의 정의를 따릅니다. 0보다 큰 경우 이와 같이 적용됩니다: 받침이 나타내는 값이 x일 경우, 1번째 위치와 x+2번째 위치에 있는 값을 서로 맞바꿉니다. 실제로 뽑기 명령은 수행되지 않으며 이 역시 현재 저장 공간이 스택이거나 큐일 경우에만 적용됩니다. 저장 공간에서 값을 x+2번 뽑아낼 수 없으면 맞바꾸지 않고 속도의 진행 방향만 뒤집습니다.

현재 저장 공간이 통로인 경우 다음을 따릅니다.

  • PASSAGE_SPEC 플래그가 NULL일 경우 ㅇ 명령과 같은 동작을 하게 됩니다.
  • 그렇지 않은 경우 PASSAGE_SPEC 플래그의 값에 해당하는 문서에 서술된 ㅍ의 동작을 하며, 또한 이 문서는 해당 문서가 ㅍ의 동작을 서술할 것을 기대합니다.

ㅅ, ㅆ

현재 글자의 받침이 가리키는 저장 공간을 a라고 합니다. 받침이 가리키는 저장 공간은 저장 공간에 서술되어 있습니다.

  • : 현재 가리키는 저장 공간을 a로 설정합니다.
  • : 현재 저장 공간에서 값을 하나 뽑아 a에 넣습니다. 현재 저장 공간에서 값을 뽑지 못하면 값을 뽑아 넣는 과정을 생략하고 속도의 진행 방향을 뒤집습니다.

현재 저장 공간에서 값을 한 번 뽑는 과정이 선행됩니다. 값을 뽑을 수 없는 경우 값을 뽑는 과정을 생략하고 속도의 진행 방향을 뒤집은 후 이하의 과정을 생략합니다.

이하에서 설명하는 "출력하다"는 "출력값으로 값을 내보내다"라는 뜻이 됩니다. "출력값"은 유니코드 문자의 나열이며, 먼저 출력값으로 내보내진 문자일수록 출력값의 앞에 존재합니다. 이 출력값은 문자열의 형태로 사용자가 프로그램 실행 중에 읽거나 파일에 저장할 수 있습니다. 이 설명 문서에서는 출력값을 stdout으로 내보내는 걸 권장합니다만, 강제하지는 않습니다.

ㅇ, ㅎ를 제외한 받침

뽑은 값을 버립니다.

뽑은 값을 x로 둘 때, 다음 과정을 수행합니다.

  1. 뽑은 값이 0보다 작은 경우, -(U+002D)을 먼저 출력합니다.
  2. 뽑은 값의 절댓값을 십진수 숫자로 출력합니다. 0(U+0030) 이상 9(U+0039) 이하의 문자를 사용하며 먼저 출력되는 문자일수록 큰 자리수의 숫자임을 뜻합니다.

뽑은 값이 음수인 경우 속도의 진행 방향을 뒤집고 이하의 과정을 생략합니다. 그렇지 않은 경우 값에 해당하는 유니코드 문자를 출력합니다. 출력할 수 없으면 출력하지 않습니다.

이하 "입력값", "입력값에서 가져오다" 등의 표현을 사용합니다. "입력값"은 유니코드 문자의 나열이며, 프로그램 실행 중에 입력값으로 유니코드 문자를 가져올 수 있고 프로그램 실행 중에 추가적으로 더 가져올 수 있습니다.

ㅇ, ㅎ를 제외한 받침

받침이 나타내는 값을 현재 저장 공간에 넣습니다. 글자에 받침이 없는 경우 0을 넣습니다. 해당 값들은 받침의 획수를 기초로 정의되었으며, 다음과 같습니다.

받침
0 (받침 없음)
2 ㄱ, ㄴ, ㅅ
3 ㄷ, ㅈ, ㅋ
4 ㅁ, ㅂ, ㅊ, ㅌ, ㅍ, ㄲ, ㄳ, ㅆ
5 ㄹ, ㄵ, ㄶ
6
7 ㄺ, ㄽ
8
9 ㄻ, ㄼ, ㄾ, ㄿ

OVERWRITE_REDEFINED_BATCHIMS 플래그가 SET일 경우, ㄳ, ㄶ, ㄵ, ㄽ, ㄾ, ㄿ는 위의 표를 따르지 않고 다른 값을 가지게 되며, 그 값은 아래와 같습니다.

받침
1
10
11
12
13
14

ㅇ 받침

입력값에서 숫자를 가져와 현재 저장 공간에 넣습니다. 해당 과정은 다음과 같습니다.

  1. 입력값에서 0(U+0030) 이상 9(U+0039) 이하의 문자들이 가장 처음에 나타나는 위치를 구간의 시작으로 삼습니다.
  2. 구간의 시작에서 0(U+0030) 이상 9(U+0039) 이하의 문자들이 뒤로 연속되어 나열되어 있는 구간들 중 가장 긴 구간을 찾습니다.
  3. 해당 구간을 10진수 숫자를 나타낸 문자열로 취급합니다. 구간의 바로 앞에 문자가 있으며 그것이 -(U+002D)일 경우, 해당 구간을 앞에 음수 기호가 생략된 10진수 음수 문자열로 취급하고, 아닐 경우 양수 기호가 생략된 10진수 양수 문자열로 취급합니다. 또한 구간 내 나중에 입력된 숫자 문자일수록 0에 가까운 자리를 뜻하는 수가 됩니다. 이 문자열을 숫자로 변환한 값을 현재 저장공간에 넣습니다.
  4. 해당 구간 및 해당 구간보다 최근에 입력된 문자들을 입력값에서 버립니다.

입력값을 가져오는 과정에서, 프로그램이 입력값을 가져올 수 없고 계속 그럴 것이라고 판단하는 경우, 프로그램을 종료합니다.

ㅎ 받침

입력값에서 유니코드 문자를 가져와 현재 저장 공간에 유니코드 문자 값을 넣습니다. 해당 과정은 다음과 같습니다. 이 과정에서의 공백 문자의 정의는 공백 문자를 따르고, 줄바꿈 문자는 줄바꿈에 언급된 문자를 의미합니다.

  1. INPUT_WHITESPACE_IGNORE_LEVEL 플래그가 ALL인 경우, 입력값 중 공백 문자 또는 줄바꿈 문자가 아닌 가장 최근에 입력된 유니코드 문자 하나를 선택합니다.
  2. INPUT_WHITESPACE_IGNORE_LEVEL 플래그가 WHITESPACE인 경우, 입력값 중 공백 문자가 아닌 가장 최근에 입력된 유니코드 문자 하나를 선택합니다.
  3. INPUT_WHITESPACE_IGNORE_LEVEL 플래그가 LINE_BREAK인 경우, 입력값 중 줄바꿈 문자가 아닌 가장 최근에 입력된 유니코드 문자 하나를 선택합니다.
  4. INPUT_WHITESPACE_IGNORE_LEVEL 플래그가 DO_NOT_IGNORE인 경우, 입력값 중 가장 최근에 입력된 유니코드 문자 하나를 선택합니다.
  5. 선택한 문자의 유니코드값을 저장공간에 넣습니다.
  6. 선택했던 위치에 해당되는 문자 및 그보다 먼저 입력된 문자들을 입력값에서 버립니다.

입력값을 가져오는 과정에서, 프로그램이 입력값을 가져올 수 없고 계속 그럴 것이라고 판단하는 경우, 프로그램을 종료합니다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment