diff options
| author | eunhhu <[email protected]> | 2026-09-30 15:38:35 +0100 |
|---|---|---|
| committer | eunhhu <[email protected]> | 2026-09-30 15:38:35 +0100 |
| commit | ee21aec10726863d8e812643e1419e4b7d0f2b51 (patch) | |
| tree | d767735579d0901c9fe2e45ea7e34d66955c7f5f /docs/design | |
| parent | 57fc44fc853da1c271f287afde62cfb4077930d2 (diff) | |
| download | pure-ee21aec10726863d8e812643e1419e4b7d0f2b51.tar.gz pure-ee21aec10726863d8e812643e1419e4b7d0f2b51.zip | |
Say how i64 will be built, and what it must not slow down (016)
Before building i64: a value slot holds a number or an i64 in the same 8
bytes (the stack, states, list cells, locals, constants), moves copy the
bits and only computing opcodes look at the type; eleven opcodes are
appended (arithmetic that fails as overflow, floor division and modulo,
compare, min, max, the two conversions), CONST and NUM_TEXT take
argument 2, and type codes are added, so v6 stays. i64-keyed lists compare
as integers without guide keys for now; folds over i64 run item by item.
JSON and queries take plain integer digits in range; views, tables and
deliveries show every digit. u32 widens to i64; i64, numbers and bools do
not deliver to each other; replacing converts when the value fits.
It is in when every check is green and the number paths keep their
speed: bank queries and TPC-C (RAM) no more than 3% slower at the median
of six interleaved pairs.
Diffstat (limited to 'docs/design')
| -rw-r--r-- | docs/design/016-bool-and-i64.md | 71 |
1 files changed, 58 insertions, 13 deletions
diff --git a/docs/design/016-bool-and-i64.md b/docs/design/016-bool-and-i64.md index 5164a7c..f69c4ff 100644 --- a/docs/design/016-bool-and-i64.md +++ b/docs/design/016-bool-and-i64.md @@ -74,19 +74,64 @@ aup의 원칙(002)을 따른다. 위치가 정수가 아니듯 참·거짓은 � ## 2단계: `i64` -1단계가 들어간 뒤 같은 방식으로 한다. 정할 것을 미리 적는다. - -- 스택 종류 i64. 값 칸은 수와 정수를 겹쳐 든다(검증기가 종류를 보장한다). -- 정수 리터럴은 문맥으로 수나 i64가 된다(`n = n + 1`에서 `n`이 i64면 `1`도 i64). -- `+ - *`는 넘치면 사건이 실패한다. `/`와 `%`는 내림한다(지금의 `%`와 같다). 0으로 나누면 `divide`. -- 수와 섞지 않는다. `number(i)`는 2^53 안에서만, `i64(x)`는 정수이고 범위 안일 때만 되고, 아니면 사건이 실패한다. -- 저장: 목록의 8바이트 열, 저장 형식은 정수(로그에서는 zigzag varint). -- JSON과 쿼리: 소수점과 지수 없는 정수 글자만 받고, 넘치면 거절한다. 보기는 정확한 자릿수다(자바스크립트의 수로 읽는 쪽은 - 2^53 너머를 잃는다: 문서에 적는다). -- 전달: u32는 i64로 넓힐 수 있다. i64와 수 사이는 넓히지 않는다. -- 키 있는 목록의 키가 될 수 있다. `sum`은 넘치면 실패한다. - -## 검사 +1단계와 같은 방식이다. 판은 올리지 않는다. 새 명령, 새 타입 번호, 0이던 자리의 값만 더하므로 v6 모듈은 그대로 유효하다. + +**언어(aup).** + +- 타입 `i64`. 상태 `state n: i64 = 0`(값을 생략하면 0), 레코드 필드 `id: i64`(기본값 0, `= 5`도 된다), 메시지·출력·인자의 + 필드 `id: i64`. `let`은 값의 타입을 따른다. +- 정수 리터럴(점과 지수가 없는 것)은 문맥의 타입이 된다. 연산이나 비교의 다른 쪽, 대입이나 필드의 자리가 문맥이다. 문맥이 + 없으면 수다. 글자 그대로 정확하게 읽는다(`9007199254740993`). i64 범위를 넘는 리터럴이나 i64 자리의 소수는 진단이다. +- `+ - *`와 단항 `-`는 넘치면 사건이 `overflow`로 실패한다. `/`와 `%`는 내림한다(나머지는 나누는 수의 부호를 따른다). 0으로 + 나누면 `divide`다. +- 수와 섞지 않는다. `i64(x)`는 x가 정수이고 범위 안일 때, `number(i)`는 |i| ≤ 2^53일 때만 되고, 아니면 사건이 `limit`으로 + 실패한다. +- 비교, `min`·`max`, 집계(`sum`은 넘치면 `overflow`), 키 있는 목록의 키(`by id`), 조각(`xs[lo .. hi]`), 보간(정확한 자릿수)이 + 된다. + +**모듈(Pure).** + +- 실행 중의 값 칸은 수와 i64를 같은 8바이트에 겹쳐 든다. 스택, 상태(`PureApp.values`), 목록의 칸(`PureCell`), 지역 칸, 명령의 + 상수가 그렇다. 옮기는 명령(LOAD, STORE, ITEM_GET·ITEM_SET, LIST_APPEND, 지역 칸, PICK, SLIDE, FIELD, SEND)은 비트를 그대로 + 옮기고, 계산하는 명령만 종류를 본다. 검증기가 종류를 보장한다. +- 새 명령을 뒤에 붙인다. I64_ADD, I64_SUB, I64_MUL, I64_DIV, I64_MOD, I64_NEG, I64_COMPARE(인자는 관계, TEXT_COMPARE처럼), + I64_MIN, I64_MAX, I64_FROM(수 → i64), NUM_FROM(i64 → 수). CONST의 인자 2는 i64 상수(값의 8바이트가 정수)이고, NUM_TEXT의 + 인자 2는 i64의 글자다. 새 실패 종류 `overflow`. +- 타입 번호: 상태 6, 레코드 필드 3, 메시지 필드 7(접두부의 8바이트, 부호 있는 little-endian), 보기 4, 지역 칸의 담는 것 3. +- 집계: FOLD의 인자에 PURE_FOLD_INTEGER(0x40)가 있으면 sum·max·min·distinct가 i64 값을 받는다(sum·max·min의 결과는 i64). + i64가 든 블록은 잎 단위로 돌지 않고 한 항목씩 돈다(필요해지면 뒤에 더한다). distinct의 집합은 빈 칸 표시를 따로 둔다 + (지금의 표시 `UINT64_MAX`는 i64의 −1이다). +- 키 있는 목록: i64 키는 정수로 비교한다. 찾기는 안내 키 없이 잎의 열을 이진 탐색한다(안내 키는 binary64라 정수에 맞지 않는다. + 정수 안내 키는 뒤의 일이다, [109](../research/109-finding-items.md)의 "다음"). 키 범위의 자동 경계(008의 키 범위)는 i64 키에 + 아직 쓰지 않는다. 조각은 i64 두 개를 받는다. +- 보기: `pure_app_view`는 수와 bool을 주고, 새 함수가 i64를 준다. + +**경계(015에 더한다).** + +- JSON과 쿼리: i64 필드는 `-?(0|[1-9][0-9]*)`(부호 `+`, 앞의 0, 점, 지수 없이)이고, −2^63부터 2^63−1까지다. 그 밖은 u32처럼 + 거절한다(JSON은 `json_type`, 쿼리는 `query`). +- 보일 때: 정확한 10진 자릿수다. 보기의 글자, 표의 JSON(JSON의 수로, 자릿수 그대로), HTTP 전달의 JSON, `pure-run`, 화면이 모두 + 같다. 자바스크립트의 `JSON.parse`처럼 binary64로 읽는 쪽은 2^53 너머에서 값을 잃는다. 그런 쪽에 보일 i64는 앱이 글자로 + 보인다(보간). +- 저장: 상태는 `values` 문서의 종류 6과 8바이트 정수다. 목록은 종류 4(i64)의 열이다. 이미지는 8바이트, 로그는 크기와 + 상관없이 zigzag varint다. +- 전달: u32는 i64로 넓힌다(정확하다). i64와 수, bool 사이는 넓히지 않는다(받지 않고 기다린다). +- 모듈 교체와 다시 열기: 수가 i64가 되면 정수이고 범위 안일 때 그 값, 아니면 기본값이다. i64가 수가 되면 |i| ≤ 2^53일 때 그 + 값, 아니면 기본값이다. bool과 i64는 0과 1로 옮긴다(i64의 다른 값은 bool의 기본값이 된다). + +**착수 기준**(구현하기 전에 정해 커밋한다). + +- 바꿀 결정: 위 모양대로 넣을지. 값 칸을 겹치는 것이 수의 경로를 느리게 하면 그 모양을 다시 본다. +- 최소 확인: + - test-module: 검증기의 거절, 산술의 끝값(±2^63 부근, 내림 나눗셈과 나머지의 부호, MIN/−1), 변환, 상태·필드·보기·보냄·지역 + 칸, i64 키 목록의 순서와 찾기·조각, 집계와 넘침, 저장·체크포인트·로그의 끝값, 교체. + - `server_meaning`에 i64 필드. 끝값(0, −1, 2^53+1, 2^63−1, −2^63)이 모든 길에서 같고, 거절할 글자(`1.0`, `1e3`, `+1`, `01`, + `"1"`, 2^63, −2^63−1)는 모든 들어오는 길이 거절한다. + - aup: 진단(섞기, 리터럴의 범위와 소수), 리터럴의 타입, 참조 모델. Vega: i64 보기의 자릿수. +- 통과 조건: 모두 초록이고, 수의 경로는 그대로다. 은행 질의([091](../research/091-queries.md))와 TPC-C(RAM, W=1)를 전과 후 + 번갈아 여섯 쌍 재서, 중앙값이 3% 넘게 느려지지 않는다. + +## 1단계의 검사 - aup: 진단(수를 조건으로, bool 산술, bool 크기 비교, bool 키), 받아들이는 형식, 참조 모델. - Pure: test-module(검증기가 bool을 섞은 모듈을 거절한다, bool 상태·필드·보기·보냄), `server_meaning`에 bool 필드(JSON, |
