aboutsummaryrefslogtreecommitdiffstats
path: root/docs/design/008-module-format.md
diff options
context:
space:
mode:
Diffstat (limited to 'docs/design/008-module-format.md')
-rw-r--r--docs/design/008-module-format.md22
1 files changed, 14 insertions, 8 deletions
diff --git a/docs/design/008-module-format.md b/docs/design/008-module-format.md
index 61e053b..f67cc37 100644
--- a/docs/design/008-module-format.md
+++ b/docs/design/008-module-format.md
@@ -34,7 +34,9 @@ v7은 027의 4단계(패턴 모으기)의 판이다. 4b로 **키별 문서**를
상태 종류 2가 text나 리스트 안의 자리이고(bool은 4, i64는 5), 명령 일곱(ANCHOR_*)이 커서와 인덱스의 열셋을 대신한다. 로드가 그것을
대상에 맞는 런타임의 명령으로 바꿔 쓴다(module-run.h). 4d로 **장치의 사건이 메시지**가 되었다: 입력의 종류는 메시지, 출력,
인자 셋이고, 키의 누름과 뗌, text 입력, 타이머, frame, 가리킴은 메시지 입력의 묶음(무엇이 그 메시지를 만드는가)이다. 핸들러의
-이벤트는 그 입력의 번호이고, DT와 TEXT_INPUT은 필드 읽기(FIELD)가 대신한다(아래 표의 번호가 당겨졌다). 4단계가 끝날 때까지 v7은 걸음마다 바뀐다(1.0 전, 생산자는 aup 하나다).
+이벤트는 그 입력의 번호이고, DT와 TEXT_INPUT은 필드 읽기(FIELD)가 대신한다(아래 표의 번호가 당겨졌다). 4e로 **보기가 아무 값**이 되었다: 보기와 열의 타입이
+레코드 필드의 것(바이트와 리스트가 더해졌다)이고, 표는 리스트 보기다. 리스트 보기는 리스트 상태 그대로나 그 지도, 또는 블록이
+낸 리스트를 행으로 가지며, 보기 항목은 20바이트다. 4단계가 끝날 때까지 v7은 걸음마다 바뀐다(1.0 전, 생산자는 aup 하나다).
**레코드 안의 리스트**(027의 2b).
- 레코드 필드의 타입 4(LIST)는 항목들의 레코드를 기본값 자리(i64)에 둔다.
@@ -86,7 +88,7 @@ v7은 027의 4단계(패턴 모으기)의 판이다. 4b로 **키별 문서**를
| | 상수 × 8 B: u32 블롭 오프셋, u32 길이 (UTF-8) |
| | 레코드 × 8 B: u32 이름, u16 첫 레코드 필드, u16 필드 수(1–16) |
| | 레코드 필드 × 16 B: u32 이름, u32 타입(0 수, 1 text, 2 bool, 3 i64, 4 리스트, 5 바이트), 8 B 기본값: 수와 bool은 f64(bool은 0이나 1), i64는 정수, text와 바이트는 u32 상수, 리스트는 항목들의 레코드 |
-| | 보기 × 16 B: u32 이름, u8 타입(0 수, 1 text, 2 표, 3 bool, 4 i64), u8 걸러진 표의 리스트 상태 + 1(그 밖에는 0), u16 표(열이면 그 표 보기 + 1, 아니면 0), u32 시작 명령, u32 명령 수. 표는 시작 명령 자리에 리스트 상태, 명령 수 0. 걸러진 표는 타입 다음 바이트에 리스트 상태 + 1, 시작·명령 수에 필터 블록 |
+| | 보기 × 20 B: u32 이름, u8 타입(레코드 필드의 것, 027의 4e: 0 수, 1 text, 2 bool, 3 i64, 4 리스트, 5 바이트), u8 0, u16 표(열이면 그 리스트 보기 + 1, 아니면 0), u16 레코드 + 1(리스트 보기와 리스트 열의 항목의 레코드, 지도는 0), u16 리스트 상태 + 1(상태 위의 리스트 보기, 그 밖에는 0), u32 시작 명령, u32 명령 수. 상태 위의 리스트 보기는 블록이 필터(없으면 0)이고, 레코드가 그 상태의 것이면 그 필드가 열이다(로드가 짓는다). 레코드가 0인 지도는 뒤따르는 열들이 행의 필드다. 상태가 없는 리스트 보기는 블록이 제 레코드의 리스트를 남긴다 |
| | 핸들러 × 12 B: u32 이벤트, u32 시작 명령, u32 명령 수 |
| | 함수 × 12 B: u32 시작 명령, u32 명령 수, u8 매개변수 수, u8 결과 수, u16 0 |
| | 서명 항목 × 4 B: 함수마다 매개변수, 그다음 결과의 차례로. u8 타입(레코드 필드의 타입: 0 수, 1 text, 2 bool, 3 i64, 4 리스트, 5 바이트), u8 0, u16 리스트의 레코드(그 밖에는 0) |
@@ -238,8 +240,9 @@ bool은 실행 중에 수의 칸에 든 0이나 1이고, i64는 같은 8바이�
- 인자(종류 6)는 열이 아닌 보기 하나를 가리키고, 보기마다 하나이며, 이름이 `보기 이름.args`다. 핸들러를 갖지 않는다. 그
보기와(표라면 그 열과 필터도) 그 안의 집계는 FIELD로 인자를 읽는다. 집계 블록은 둘레 블록의 메시지나 인자를 읽을 수 있다
(읽기뿐: 응답은 핸들러 자신의 코드에만 있다).
-- 표는 리스트 상태를 가리키고 열은 앞에 나온 표를 가리킨다. 표 밖의 이름은 한 이름공간이고, 열 이름은 표
- 안에서만 유일하다.
+- 리스트 보기는 리스트 상태를 가리키거나(그 레코드이거나 지도) 블록이 리스트를 낸다(레코드가 있다). 열은 앞에 나온 지도를
+ 가리키고, 리스트 열은 항목의 레코드를 적는다. 레코드의 리스트 보기는 열을 갖지 않는다(필드가 열이다). 보기 밖의 이름은 한
+ 이름공간이고, 열 이름은 리스트 보기 안에서만 유일하다. 지은 열까지 보기는 64개다.
- 반복(LOOP, EACH)은 제 피연산자 말고는 빈 스택에서 연다. 반복의 블록은 그 실행의 스택 바닥에서 시작하므로, 아래에 값을 둔 반복은
스택의 64칸을 넘을 수 있었다(검증을 지난 모듈이 실행기를 죽였다. 2c에서 찾아 막았다).
- 함수(2c): 블록은 매개변수를 스택에 두고 시작하고, 모든 길이 RETURN으로 끝난다. RETURN은 자기 함수의 결과 타입을 맨 위에서
@@ -361,8 +364,11 @@ text·리스트가 남을 때만 위치를 유지한다.
ANCHOR_AT, ANCHOR_STORE)를 만든다. 그래서 인터페이스(Vega)는 앱 코드 없이 목록의 클릭을 포커스로 옮긴다. 4d 전에는 핸들러 없는
이벤트(`pure_app_point`)였고, 옮길 인덱스를 보기에서 찾았다(`pure_module_position`).
-표 보기는 리스트 항목마다 행 하나를 가진다(`pure_app_rows`). 걸러진 표는 필터 블록이 참을 남긴 항목마다
-행 하나를 가진다(항목 순서 그대로). 필터는 상태가 바뀐 뒤 처음 행을 물을 때 항목마다 한 번 돌고, 그 결과(행 → 항목)를
+리스트 보기는 리스트 항목마다 행 하나를 가진다(`pure_app_rows`). 걸러진 리스트 보기는 필터 블록이 참을 남긴 항목마다
+행 하나를 가진다(항목 순서 그대로). 블록이 리스트를 내는 보기(027의 4e)는 바뀜 뒤 처음 물을 때 블록을 한 번 돌고, 그 리스트를
+저장 형태의 리스트로 옮겨 다음 바뀜까지 행과 칸에 쓴다. 레코드의 필드인 열은 계산 없이 항목의 필드를 읽는다. 리스트의 칸은
+그 항목들을 3단계의 저장 형태로 빌려주고(`pure_app_cell_items`), `pure_items_next`가 항목 하나의 칸들을 읽는다. 바이트의
+보기와 칸은 text처럼 빌려준다(`pure_app_view_text`, `pure_app_cell_text`). 필터는 상태가 바뀐 뒤 처음 행을 물을 때 항목마다 한 번 돌고, 그 결과(행 → 항목)를
다음 변경까지 쓴다. 칸마다 다시 거르지 않는다. 변경 번호는 이벤트, 가리키기, 저장 실패의 되돌리기, 모듈 교체마다
오르고 되돌아가지 않는다. 열의 `ROW`는 행이 아니라 항목이다. 호스트는 `pure_app_row_item`·`pure_app_item_row`로 행과
항목을 오간다. 그래서 포커스(인덱스, 곧 항목)를 걸러진 목록의 행으로 보이고, 클릭한 행을 항목으로 가리킨다. 호스트는 보여 줄 칸만
@@ -477,8 +483,8 @@ ANCHOR_AT, ANCHOR_STORE)를 만든다. 그래서 인터페이스(Vega)는 앱 �
| 요청 | 뜻 |
|---|---|
-| `GET /views/이름` | 보기의 값. 수는 가장 짧은 왕복 10진수, bool은 `true`·`false`, text는 UTF-8 그대로(`text/plain`). text 상태를 그대로 보이는 보기(`view page = note`)는 저장된 익스텐트를 빌려준다([079](../research/079-lent-views.md)) |
-| `GET /views/표?from=N&count=M` | 표의 행: `{"rows":전체,"from":N,"items":[{열: 값}…]}`(`application/json`, bool 열은 `true`·`false`). 요청한 행의 칸만 계산한다. 값이 없는 칸은 `null` |
+| `GET /views/이름` | 보기의 값. 수는 가장 짧은 왕복 10진수, bool은 `true`·`false`, text는 UTF-8 그대로(`text/plain`), 바이트는 그대로(`application/octet-stream`). text 상태를 그대로 보이는 보기(`view page = note`)는 저장된 익스텐트를 빌려준다([079](../research/079-lent-views.md)) |
+| `GET /views/표?from=N&count=M` | 리스트 보기의 행: `{"rows":전체,"from":N,"items":[{열: 값}…]}`(`application/json`, bool 열은 `true`·`false`, 바이트는 16진 문자열, 리스트는 그 레코드의 필드를 가진 객체의 배열). 요청한 행의 칸만 계산한다. 값이 없는 칸은 `null` |
| `GET /views/이름?인자=값…` | 인자를 받는 보기(표라면 `from`·`count`와 함께). 값은 `%XX`를 풀어 읽고, 고정 필드는 메시지의 쿼리 필드와 같다. 빠진 고정 인자, 모르는 이름, 두 번 준 인자, 타입이 다른 값은 400 `invalid`. 등록한 질의도 같다(`GET /queries/이름?인자=값`) |
| `POST /inputs/이름` | 이벤트. text 입력은 본문이 text, 키의 누름은 누름 뒤 같은 키의 뗌(받는 입력이 있으면). 타이머·frame·가리킴과 출력·인자에는 `no_input`. 메시지는 고정 필드(u32, 수, bool)를 쿼리(`?points=3`, `?done=true`, 그룹 안이면 `?to.zip=7`)로, 가변 필드 하나를 본문으로 받거나, `Content-Type: application/json` 본문의 객체로 필드를 받는다(문자열은 바이트·text, 수는 u32·수, `true`·`false`는 bool, 그룹은 안의 객체). 응답 본문은 핸들러의 `reply`(메시지 필드) |
| `POST /inputs/이름` + `X-Pure-Source`·`X-Pure-Sequence` | 다른 앱의 출력에서 전해진 메시지(`pure_app_deliver`): 번호마다 한 번 적용하고, 이미 들은 번호는 200. 답에 `X-Pure-Batch: 256`을 싣고, `X-Pure-Count: N`이면 본문은 N개 객체의 JSON 배열(연속 번호, 한 묶음에서 차례로 적용) |