저는 김프린입니다. 본명은 김선경. 이 책의 모든 장을 끝까지 책임지는 작가이고, 지금부터 열네 개의 장을 통과해 트릿 한 톨에서 시작한 셈법이 어떻게 한 채의 세계와 한 종류의 부(富)에까지 닿는지를 보여 드리려 합니다. 그러니 첫 장은 가장 천천히 가겠습니다. 여기서 까는 격자가 흔들리면 그 위에 올린 모든 것이 함께 흔들리기 때문입니다.
저는 오랫동안 하나의 질문을 품고 있었습니다. 왜 우리의 모든 기계는 오직 두 상태만 알아야 하는가. 0과 1, 켜짐과 꺼짐. 그런데 현실의 어떤 신호등도 빨강과 파랑만으로 교차로를 지키지 못합니다. 건너가려는 발과 멈추려는 발 사이에 노란불이 켜져 "아직"이라고 말합니다. 벽의 스위치에는 눌림도 안 눌림도 아닌 고장이라는 제3의 상태가 있고, 우리는 하루에도 수백 번 "확실하지 않다"고 말합니다. 그런데 이진의 세계에서 "모름"과 "중립"은 일급 시민이 아니었습니다. 두 비트 이상을 비틀어 엮어야 겨우 흉내 낼 수 있는 파생물일 뿐이었습니다.
크라우니코드는 다른 전제에서 출발합니다. 참과 거짓 사이에 영(零)을 놓고, 그 셋을 하나의 물리적 단위로 직결하기로 한 것입니다. 이것은 철학적 선언이 아니라 설계 규율입니다. 메모리 정렬부터 명령어 인코딩까지, 3의 거듭제곱으로 모든 계층을 꿰뚫는다는 규율 말입니다. 이 장은 그 출발점의 명세입니다 — 4상 균형 3진수 체계, 그 위에 한 트릿으로 자신을 선언하는 큐브, 그리고 인코딩이 곧 위치가 되는 ISA729. 책 전체가 딛고 설 첫 격자를 여기서 한 번 단단히 깔아 두겠습니다.
크라우니코드의 기본 단위는 트릿(trit)이며, 네 가지 기호로 표현된다.
노란불을 떠올려 보면 좋다. T는 초록불, A는 빨간불, O는 그 사이에서 판단을 보류하는 노란불이다. 여기에는 흔들리지 않는 두 약속이 있다. 하나, U는 어디까지나 구분자이며 값을 가지지 않는다. 둘, 음수 −1은 언제나 A로만 표현하며 다른 형태로는 나타나지 않는다. U는 칸막이이고 음수의 자리는 오직 A 하나뿐 — 이 두 정의는 책 전체에서 단 한 번도 다시 펴지지 않고 그대로 불려 쓰인다.
정수를 트릿 시퀀스로 변환할 때는 균형 3진수 인코딩을 따른다. 3으로 나눈 나머지 r이 2인 경우, r을 −1로 바꾸고 몫에 1을 더한다. 예컨대 10을 변환하면 10 = 3×3 + 1이므로 자리 하나에 +1을 두고, 남은 3 = 3×1 + 0이므로 다음 자리에 0, 그 위 1을 마저 두어 AT(+1, +1)로 떨어진다. 이 보정 규칙이 핵심이다. 표준 3진수라면 자릿값이 0, 1, 2에 퍼져 덧셈과 뺄셈의 복잡도가 서로 다르지만, −1·0·+1만 쓰는 균형 형태에서는 두 연산이 동등한 무게를 갖는다. 저울의 양쪽 접시가 똑같이 생긴 것처럼, 더하기와 빼기가 같은 셈으로 다뤄진다.
이 균형 체계로 26 트릿이 표현하는 최대 정수는 (3²⁶ − 1) / 2 = ±141,214,768,240이며, 이는 64비트 정수 범위를 모두 수용한다.
여기에 한 가지 변환 약속을 미리 받아 두어야 한다. 뒤의 인코딩 전부가 이 약속을 딛고 서기 때문이다. 트릿 두 개를 모으면 3² = 9개의 조합이 생기고, 이를 정수 0부터 8까지에 대응시킨다.
| 트릿 쌍 | AA | AO | AT | OA | OO | OT | TA | TO | TT |
|---|---|---|---|---|---|---|---|---|---|
| 정수 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
순서는 A → O → T, 즉 −1 → 0 → +1의 오름차순이다. 왜 이 순서만 유효한가. 두 자리를 이 오름 순서 그대로 세면 0부터 8까지가 빈틈도 겹침도 없이 한 줄로 메겨지기 때문이다. 다른 순서를 택하면 어떤 정수는 두 번 나타나고 어떤 정수는 영영 표현되지 않는다. 그래서 이것은 취향이 아니라 유일한 답이다.
크라우니코드의 기본 처리 단위는 큐브(Cube)로, 27개의 트릿(3³)으로 이루어진다. 메모리에서는 7바이트 데이터에 1바이트 패딩을 더해 8바이트로 정렬된다. 트릿 인덱싱은 최하위 T1부터 최상위 T27까지 차례로 진행된다.
큐브의 정체성은 최상위 트릿 T27 한 개가 결정한다.
앞서 본 고장난 스위치를 다시 떠올려 보면 좋다. 그 스위치는 눌림·안 눌림 말고도 "고장"이라는 제3의 상태를 자신에게서 바로 읽을 수 있었다. 큐브의 T27도 똑같이, 메타데이터 테이블을 따로 두지 않고 자신이 무엇인지를 한 트릿으로 선언한다.
데이터 큐브인 경우, 다음 두 트릿이 정보를 더 담는다.
역할·타입·크기 세 트릿이 큐브 자신에 내재함으로써, 런타임은 별도 타입 테이블을 조회하지 않고도 값을 판별한다. 이것이 가능한 이유는 큐브가 충분히 크기(27 트릿) 때문이다. 작은 그릇이 작은 것을 담으려 하면 또 다른 메타정보를 요구하는 악순환이 시작되지만, 충분한 크기를 한 번에 잡으면 그 순환이 끊긴다. 역할트릿(T27)·타입트릿(T26)·크기트릿(T25)으로 정체를 자기 안에 담는 이 큐브 정의가 권 전체의 기준이며, 뒤 장들은 이 한 단위를 새로 정의하지 않고 가리키기만 한다.
큐브의 메모리 레이아웃은 다음과 같다.
byte[0]: T1 T2 T3 T4
byte[1]: T5 T6 T7 T8
byte[2]: T9 T10 T11 T12
byte[3]: T13 T14 T15 T16
byte[4]: T17 T18 T19 T20
byte[5]: T21 T22 T23 T24
byte[6]: T25 T26 T27 (unused)
byte[7]: (padding)
역할 판별은 헤더도, 길이 필드도, 타입 태그도 없이 T27 한 트릿으로 갈린다. 데이터면 하위 트릿을 균형 3진 정수로 읽고, 명령이면 하위 6트릿을 opcode로 디코딩하며, 체이닝이면 직전 큐브를 확장한다. 스스로 말한다는 것 — 이 원리가 크라우니코드를 관통한다.
큐브가 데이터와 명령을 같은 형식에 담는다면, 그 명령을 누가 어떤 언어로 쓰는가가 다음 질문이 된다. 크라우니 헌법 9조(2026-05-21 선언)가 이 답을 명시한다. 한선씨 RPN(역폴란드 표기법)은 ISA729 명령어 집합과 1:1로 매핑된다. 컴파일 경로는 둘로 나뉜다.
고수준 경로: hanseonc_high 컴파일러가 C-like 구문의 한선씨 코드를 TOAU 바이트코드로 변환한다. 함수·조건문·반복문을 익숙한 문법으로 쓰게 해 학습 곡선을 낮추는 이행 보조 역할이다.
정통 경로: hanseonc_std 컴파일러가 RPN 형태의 한선씨 코드를 ISA729에 1:1 대응하는 TOAU 바이트코드로 생성한다. 이것이 정통 방식이며, 각 한글 키워드가 정확히 하나의 명령어로 변환된다. 스택에 값을 쌓고 연산자를 만나면 즉시 실행하는 RPN의 역순 표기는 큐브의 순차 처리와 자연스럽게 맞아떨어진다.
최종적으로 단일 가상 머신 crownyc가 TOAU 바이트코드를 실행한다. 상위 언어에서 한선씨 RPN을 거쳐 기계어로 오르는 상승 방향만 허용되며, 역방향 변환은 금지된다. 이 제약이 보장하는 것은 명확함이다. 소스코드를 보면 어떤 명령이 실행될지 의심할 여지가 없다.
ISA729는 729개의 명령어 슬롯을 가지며, 9개 섹터(sector) × 9개 그룹(group) × 9개 커맨드(command)로 구성된다(9 × 9 × 9 = 729). 이 규칙적 분할이 가능한 이유는 3의 거듭제곱이 곧 트릿의 조합과 일치하기 때문이다. 인코딩 공식은 간단하다.
opcode = sector × 81 + group × 9 + command
이 공식이 말하는 핵심은 하나다. 명령어의 번호가 곧 그 명령이 놓일 메모리 위치다. 흔한 기계에서 명령어 번호는 그저 사전에 매겨진 색인이고, 그 번호가 어디에 사는지는 또 다른 조회 표를 펼쳐야 안다. ISA729에는 그 중간 표가 없다. 섹터·그룹·커맨드를 곱하고 더하면 그 자리가 바로 큐브 안의 트릿 배치로 떨어진다.
구체적으로, 최하위 6개 트릿(T1~T6)을 두 개씩 묶어 앞의 변환표대로 0~8 정수로 읽으면 command·group·sector가 차례로 나타난다. 나머지 윗자리는 O로 채우고, T27은 O로 두어 "나는 명령이다"라고 선언한다. 그러면 해석기는 번호를 주소로 번역하는 수고가 없다. 번호가 이미 주소이기 때문이다 — 빠르고, 캐시에 친화적이고, 무엇보다 거짓말을 할 수 없는 구조다.
9개 섹터가 각각 어떤 기능을 맡는지, 인코딩을 트릿 단위로 풀어내는 디코딩 예제와 729 슬롯의 구현 현황은 뒤 장에서 본격적으로 펼친다. 이 장에서는 "인코딩이 곧 메모리 위치"라는 원리 하나만 못 박아 둔다. 그 원리만 손에 쥐고 있으면, 나중에 마주칠 섹터 표와 디코딩 과정이 새로운 규칙이 아니라 같은 공식의 펼침임을 알아볼 수 있다.
크라우니코드는 한글 문자에 대해 고밀도 인코딩을 제공한다. 한글 한 글자는 9개의 트릿(3개의 트라이트)으로 인코딩되며, 초성(19값), 중성(21값), 종성(28값)으로 나뉜다. 한글이 초·중·종 셋으로 짜인 글자라는 사실과, 트릿이 셋으로 묶이는 3진 구조가 정확히 맞물린다.
그 결과, 한글 세 글자가 정확히 하나의 큐브(27 트릿)에 들어맞는다. 메모리 절약은 자동이다. 추가 CPU 비용 없이, 한글의 자모 조합 구조 자체가 곧 압축이 된다. UTF-8 대비 약 25%의 절약(3바이트 → 2.25바이트/문자)이 발생한다.
크라우니코드의 모든 단위는 3의 거듭제곱 위에서 정렬된다.
이 규율은 미감이 아니라 메모리·연산·언어를 가로지르는 설계 철학입니다. 시스템이 커질수록 복잡도는 기하급수적으로 늘어나는데, 그 복잡도를 감당하는 가장 좋은 방법은 한 가지 원리를 끝까지 밀어붙이는 것이라고 저는 믿습니다. 3진수라는 선택도, 큐브라는 단위도, ISA729라는 슬롯 수도 모두 그 하나의 원리에서 나왔습니다. 노란불도, 고장난 스위치도, "확실하지 않다"는 말도 — 이진의 세계가 변두리로 밀어 두었던 그 세 번째 자리들을, 이 격자는 처음부터 한가운데에 앉혔습니다.
이제 첫 격자는 깔렸습니다. 다음 장 "큐브와 27트릿"에서는, 같은 손으로 숫자를 쌓던 이 셈법이 한 채의 큐브를 어떻게 메모리 공간으로, 시간 좌표로, 그리고 세계관의 기초 격자로까지 펼쳐 나가는지를 함께 보겠습니다.
첫 번째 책은 선물이에요. 가입하면 100맘을 드리니까, 두 번째 책부터 자유롭게 읽을 수 있어요. 친구를 추천하면 50맘도 생겨요.