가희
- 1판: 2015. 3. 3. (폐지)
- 2판: 2016. 1. 29. (무효)
가희는 한글로 된 난해한 프로그래밍 언어입니다.
이 문서는 아희 확장에 대해 설명하고 있습니다. 이 문서에서 설명하지 않은 부분은 아희 표준 사양 페이지를 참고하세요.
코드
가희 코드는 언제나 다음 조건을 만족합니다.
- 가희 코드는 BOM 없는 UTF-8로 인코딩되어있어야 합니다.
- 가희 코드는 줄 수와 줄 길이가 각각 32비트의 부호를 갖지 않는 정수의 최대값보다 적어야만 합니다.
- 줄바꿈 기호를 제외한 모든 문자는 한 칸으로 취급하며, 반각과 전각은 구분하지 않습니다.
- 줄바꿈 기호는
CRLF
,CR
또는LF
중 하나입니다. 하나의 코드에 여러 줄바꿈 기호를 섞어 사용할 수는 없습니다. - 줄바꿈 기호는 코드 맵을 만들 때만 사용되고, 문자로서 취급되지는 않습니다.
- 코드 맵은 언제나 직사각형의 형태를 갖게 됩니다. 코드 맵의 오른쪽 끝은 가장 긴 칸을 갖는 줄의 너비이고, 그보다 짧은 칸을 갖는 줄은 가장 긴 칸을 갖는 줄의 길이에 맞게 줄 끝을 가상의 공백 문자로 채웁니다.
값
값은 최소 32비트의 부호를 갖는 정수를 의미합니다. 값은 수치에 상응하는 유니코드 문자로 변환할 수 있습니다.
공간
공간은 값을 기억 또는 송수신할 수 있는 모든 것을 의미합니다. 끝소리 없음을 제외한 모든 공간은 모든 스레드에서 공유합니다.
스택
스택은 먼저 넣은 값이 나중에 나오게 되는 형태의 공간을 이야기합니다. 끝소리 ㅇ과 ㅎ을 제외한 모든 공간의 기본값입니다. 가질 수 있는 값의 갯수는 적어도 32비트의 부호를 갖지 않는 정수의 최대값이어야 합니다.
큐
큐는 먼저 넣은 값이 먼저 나오게 되는 형태의 공간을 이야기합니다. 끝소리 ㅇ의 기본값입니다. 가질 수 있는 값의 갯수는 적어도 32비트의 부호를 갖지 않는 정수의 최대값이어야 합니다.
스트림(통로)
스트림은 외부와 데이터를 주고받는 형태의 공간을 이야기합니다. 끝소리 ㅎ의 기본값이며, 따로 설정하지 않았을 경우 *nix의 경우 /dev/null
, Windows의 경우 NUL
로 연결됩니다. 읽고 쓸 수 있는 값의 갯수는 환경에 따라 다를수 있습니다.
명령
- 아무 끝소리는 끝소리가 없는 상태를 포함합니다.
- 먼저 이동은 가운뎃소리를 읽은 뒤에 명령을 처리하고 이동합니다. 오류로 인한 방향 반전과 가리키는 곳이 바뀌는 것으로 인한 방향 변경을 무시합니다.
- 나중 이동은 명령을 처리한 뒤에 가운뎃소리를 읽고 이동합니다. 오류로 인한 방향 반전과 가리키는 곳이 바뀌는 것으로 인한 방향 변경을 반영합니다.
없음
- ㅇ + 아무 끝소리: (먼저 이동) 아무것도 하지 않음.
갈피
갈피는 고급 언어의 레이블에 해당하는 부분입니다. 끝소리 있는 ㅋ 명령 등으로 다른 갈피로 이동하기 전에 포인터가 가리키는 위치가 포인터 스택에 들어갑니다. 이 후에 끝소리 없는 ㄱ 명령이나 ㅋ 명령을 사용하면 포인터 스택에서 이전 위치를 불러와 해당 위치로 이동하게 됩니다. 포인터 스택이 비어있으면 오류로 판단하고 방향을 반전합니다. ㄲ 명령을 받침 없이 사용해 멀티 스레드를 시작하면 코드의 왼쪽 위부터 아래로 읽기 시작하는 규칙이 적용됩니다. 갈피는 끝소리 없음을 제외하고는 비어 있으며, 빈 갈피로 가려고 하면 오류로 처리되어 방향이 반전됩니다. 끝소리 없음을 제외한 모든 갈피는 덮어쓸 수 있습니다.
- ㄱ + 끝소리 없음: (나중 이동) 갈피를 부른 곳으로 돌아가기. (새롬)
- ㄱ + ㅇ 또는 ㅎ을 제외한 끝소리: (먼저 이동) 끝소리 갈피를 지금 가리키는 곳으로 지정. (새롬)
- ㄲ + ㅇ 또는 ㅎ을 제외한 끝소리: (먼저 이동) 끝소리 갈피에서 새 스레드. (새롬)
- ㅋ + 끝소리 없음: (먼저 이동) 갈피를 부른 곳으로 돌아가기. (새롬)
- ㅋ + ㅇ 또는 ㅎ을 제외한 끝소리: (먼저 이동) 끝소리 갈피로 가기. (새롬)
셈
기본적인 동작은 아희와 같습니다.
- ㄴ + 끝소리 없음: (나중 이동) 두 값을 뽑아 나중 값에 나눈 값을 넣기.
- ㄴ + ㅇ 또는 ㅎ을 제외한 끝소리: (나중 이동) 두 값을 뽑아 나중 값에 나눈 값을 넣기. (새롬) 1
- ㄷ + 끝소리 없음: (나중 이동) 두 값을 뽑아 나중 값에 더한 값을 넣기.
- ㄷ + ㅇ 또는 ㅎ을 제외한 끝소리: (나중 이동) 두 값을 뽑아 나중 값에 더한 값을 넣기. (새롬) 1
- ㄸ + 끝소리 없음: (나중 이동) 두 값을 뽑아 나중 값에 곱한 값을 넣기.
- ㄸ + ㅇ 또는 ㅎ을 제외한 끝소리: (나중 이동) 두 값을 뽑아 나중 값에 곱한 값을 넣기. (새롬) 1
- ㄹ + 끝소리 없음: (나중 이동) 두 값을 뽑아 나중 값에 나눈 나머지 값을 넣기.
- ㄹ + ㅇ 또는 ㅎ을 제외한 끝소리: (나중 이동) 두 값을 뽑아 나중 값에 나눈 나머지 값을 넣기. (새롬) 1
- ㅌ + 끝소리 없음: (나중 이동) 두 값을 뽑아 나중 값에 뺀 값을 넣기.
- ㅌ + ㅇ 또는 ㅎ을 제외한 끝소리: (나중 이동) 두 값을 뽑아 나중 값에 뺀 값을 넣기. (새롬) 1
읽고 쓰기
기본적인 동작은 아희와 같습니다.
- ㅁ + 끝소리 없음: (나중 이동) 한 값을 뽑아 버리기.
- ㅁ + ㅇ 또는 ㅎ을 제외한 끝소리: (나중 이동) 한 값을 뽑아 버리기. (새롬) 1
- ㅁ + 끝소리 ㅇ: (나중 이동) 한 값을 뽑아 숫자로 써내기.
- ㅁ + 끝소리 ㅎ: (나중 이동) 한 값을 뽑아 문자로 써내기.
- ㅂ + ㅇ 또는 ㅎ을 제외한 아무 끝소리: (먼저 이동) 끝소리 값을 넣기.
- ㅂ + 끝소리 ㅇ: (나중 이동) 숫자를 값으로서 읽어들여 넣기.
- ㅂ + 끝소리 ㅎ: (나중 이동) 문자를 값으로서 읽어들여 넣기.
큐와 스택
기본적인 동작은 아희와 같습니다.
- ㅃ + 끝소리 없음: (나중 이동) 한 값을 뽑아 큐라면 맨 앞에, 스택이라면 맨 위에 두 번 넣기.
- ㅃ + ㅇ 또는 ㅎ을 제외한 끝소리: (나중 이동) 한 값을 뽑아 큐라면 맨 앞에, 스택이라면 맨 위에 두 번 넣기. (새롬) 1
- ㅍ + 끝소리 없음: (나중 이동) 앞쪽 두 값을 서로 바꾸기.
- ㅍ + ㅇ 또는 ㅎ을 제외한 끝소리: (나중 이동) 앞쪽 두 값을 서로 바꾸기. (새롬) 1
스트림 (통로)
ㅍ 명령의 동작을 불분명하게 나타내고 있는 아희와는 달리, 가희에서는 나중 이동을 하는 ㅇ 명령처럼 동작합니다.
- ㅃ + 끝소리 없음: (나중 이동) 마지막으로 보낸 값을 넣기.
- ㅃ + ㅇ 또는 ㅎ을 제외한 끝소리: (나중 이동) 마지막으로 보낸 값을 넣기. (새롬) 1
공간
아희와 같습니다.
- ㅅ + 아무 끝소리: (나중 이동) 끝소리 공간을 선택.
- ㅆ + 아무 끝소리: (나중 이동) 한 값을 뽑아 끝소리 공간에 넣기.
견주기
ㅉ 명령으로 난수를 생성할 수 있습니다. 뽑은 값이 3이면 0부터 2 사이의 임의의 값을 넣습니다. 값을 뽑지 못했다면 오류로 판단합니다.
- ㅈ + 끝소리 없음: (나중 이동) 두 값을 뽑아 나중 값이 크거나 같으면 1, 아니면 0을 넣기.
- ㅈ + ㅇ 또는 ㅎ을 제외한 끝소리: (나중 이동) 두 값을 뽑아 나중 값이 크거나 같으면 1, 아니면 0을 넣기. 1
- ㅉ + 끝소리 없음: (나중 이동) 한 값을 뽑아 0이면 뽑은 값을, 양수면 0부터 뽑은 값-1 사이의 아무 값을, 음수면 -1부터 뽑은 값 사이의 아무 값을 넣기. (새롬)
- ㅉ + ㅇ 또는 ㅎ을 제외한 끝소리: (나중 이동) 한 값을 뽑아 0이면 뽑은 값을, 양수면 0부터 뽑은 값-1 사이의 아무 값을, 음수면 -1부터 뽑은 값 사이의 아무 값을 넣기. (새롬) 1
- ㅊ + 끝소리 없음: (나중 이동) 한 값을 뽑아 0이 아니면 가운뎃소리의 방향, 아니면 반대 방향으로 옮기기.
- ㅊ + ㅇ 또는 ㅎ을 제외한 끝소리: (나중 이동) 한 값을 뽑아 0이 아니면 가운뎃소리의 방향, 아니면 반대 방향으로 옮기기. 1
끝내기
- ㅎ + 끝소리 없음: (먼저 이동) 한 값을 뽑아 돌려준 뒤 끝내기.
이동
어떤 가운뎃소리는 이동 방향과 칸 수를 갖습니다.
가운뎃소리 | 방향 | 칸 수 | 아희 호환성 |
---|---|---|---|
ㅏ | → | 1 | ✓ |
ㅑ | → | 2 | ✓ |
ㅓ | ← | 1 | ✓ |
ㅕ | ← | 2 | ✓ |
ㅗ | ↑ | 1 | ✓ |
ㅛ | ↑ | 2 | ✓ |
ㅜ | ↓ | 1 | ✓ |
ㅠ | ↓ | 2 | ✓ |
ㅘ | ↗ | 1 | 2 |
ㅝ | ↙ | 1 | 2 |
어떤 가운뎃소리는 이동 방향을 변경합니다.
가운뎃소리|설명|아희 호환성
:-:|:-|:-:
ㅡ|세로축 방향을 반전합니다.|✓
ㅢ|가로·세로축 방향을 반전합니다.|✓
ㅣ|가로축 방향을 반전합니다.|✓
커서가 코드 맵 밖으로 나갔다면 반대쪽 끝으로 돌아갑니다.
반받아우
다망희아
위 코드는 아래와 같은 흐름으로 실행됩니다.
㉠㉡㉢㉣
㉥㉦㉧㉤㉥
커서가 코드 맵 밖으로 한 칸 더 나갔다면 반대쪽 끝에서 한 칸 떨어진 위치로 돌아갑니다.
뱐뱓어우
먕더희야
위 코드는 아래와 같은 흐름으로 실행됩니다.
㉠㉢㉡㉣
㉦㉥㉧㉤ ㉥
예제
다음은 0으로 나눌 때 42가 나오는 가희 코드입니다.
국 -- 갈피 ㄱ 등록
밝밦뚜 -- 42를 넣기
규 -- 선언 시에는 돌아갈 곳이 없으므로 오류로 처리되어 방향 반전
오류에서 왔다면 해당 명령이 있던 곳으로 돌아감
반부 -- 2와 0을 차례대로 넣기
뉵 -- 나누는 중 오류가 발생했을 경우 갈피 ㄱ으로 가기 (나중 이동)
돌아왔을 때 이 명령의 방향과 거리가 유지됨
망희 -- 값을 출력하고 종료
사족
가희는 아희에 기능을 더했다(加)는 뜻과, 가희의 가장 큰 특징인 갈피 관련 기능이 ㄱ 묶음이라는 것을 나타내는 이름입니다. 가희
자체는 실행시키면 방향이 뒤바뀌어 안전하게 끝나는, 가희 언어로 쓰여진 코드입니다. 하지만 사실은 歌姫라는 어감이 아름다워서 이렇게 정했습니다.
처리기
가희 처리기는 다음과 같은 조건을 만족해야 합니다.
- 완전한 아희 코드는 완전한 가희 코드입니다. 가희와 같은 코드 규칙과 이동 규칙을 갖는 아희 처리기에서 완전한 아희 코드를 실행한 결과는 같은 코드를 가희 처리기에서 실행한 결과와 정확히 일치해야 합니다. 3
- 처리기는 처리를 위해 입력받은 코드를 절대로 변경해선 안됩니다. 여기에는 입력받은 코드의 선행·후행 공백을 무시하거나, 마지막 줄 뒤에 가상의 빈 줄을 추가하는 것 따위도 해당됩니다.
- 줄바꿈 기호는
CRLF
,CR
또는LF
중 하나입니다.CRLF
가 하나라도 있을 경우CRLF
를 줄바꿈 기호로 사용하고,CRLF
가 없고CR
이 하나라도 있을 경우CR
를 줄바꿈 기호로 사용하고, 둘 다 없으면LF
를 줄바꿈 기호로 사용합니다.