aboutsummaryrefslogtreecommitdiffstats
path: root/docs/design/002-dsl-direction.md
diff options
context:
space:
mode:
Diffstat (limited to 'docs/design/002-dsl-direction.md')
-rw-r--r--docs/design/002-dsl-direction.md47
1 files changed, 47 insertions, 0 deletions
diff --git a/docs/design/002-dsl-direction.md b/docs/design/002-dsl-direction.md
index efdca29..f05123f 100644
--- a/docs/design/002-dsl-direction.md
+++ b/docs/design/002-dsl-direction.md
@@ -596,3 +596,50 @@ on remote {
검증: 진단 7건(펼치기가 끝이 아님, 펼칠 수 없는 source, 핸들러 밖의 메시지, 그룹 안의 펼치기, 채워지지 않은 send 필드, 필드가
빠진 항목 전체, 레코드가 아닌 값). 펼치기와 항목 전체를 쓴 모듈과 필드를 적은 모듈이 바이트로 같다. `pure-run`에서 키가 다른 항목
전체 대입은 `limit`으로 실패하고 값을 바꾸지 않으며, 키가 같은 것은 바꾼다.
+
+### 바이트, 비트, 수의 리스트 (Pure 027의 1단계)
+
+Pure [027](/srv/git/pure.git)(`docs/design/027-computation-core.md`)의 1단계이고, 세상의 명세가 aup에서 처음 부딪치던 것 가운데 셋을
+연다(Pure `docs/research/140-spec-suite.md`). `examples/sha256.aup`가 그것으로 쓴 SHA-256이다.
+
+```text
+input hash = message { data: bytes }
+fn rotr(x, n) = (x >> n | x << (32 - n)) & 0xffffffff
+on hash {
+ let k: list of i64 = [0x428a2f98, 0x71374491, ...] # 리스트의 처음 값
+ let a, b = hash.data[0], hash.data[1] # 메시지 바이트의 그 자리(i64 0–255)
+ a, b = b, a # 값을 먼저 모두 계산하고 한 번에 준다
+ let hex: list of i64
+ hex.append(48 + (a >> 4))
+ digest = text(bytes(hex)) # i64 리스트의 바이트
+}
+```
+
+- **16진 리터럴** `0x…`는 어디서나 i64다.
+- **비트 연산** `&`, `|`, `^`, `~`, `<<`, `>>`는 i64를 끝없는 2의 보수 위의 정수로 계산한다(파이썬의 정수와 같은 뜻).
+ - `x << n`은 x·2^n이고, i64를 넘으면 이벤트가 `overflow`로 실패한다.
+ - `x >> n`은 내림한 x / 2^n이다.
+ - 시프트 수는 수나 i64이고, 0–63 밖이면 `limit`이다.
+ - 우선순위는 파이썬과 같다: 비교 < `|` < `^` < `&` < 시프트 < `+ -` < `* / %` < 단항. 그래서 `e & f ^ ~e & g`는 `(e & f) ^ ((~e) & g)`다.
+ - 수에 쓰면 진단이 변환을 권한다(`bit operations take i64s, not numbers: convert, as in i64(x)`).
+- **자리의 바이트** `b[i]`는 바이트 값(메시지와 인자의 필드, fn의 매개변수, `bytes(t)`)의 그 자리 바이트를 i64로 준다.
+ - 자리는 수나 i64다. 정수가 아니거나 값 밖이면 `limit`이다.
+ - text는 바이트를 거쳐 읽는다(`bytes(t)[i]`). 글자로 읽기는 2단계다.
+- **수의 리스트** `list of i64`(`number`, `bool`, `text`도)는 필드가 `value` 하나인 레코드의 리스트로 Pure에 간다.
+ - `xs.append(5)`처럼 값 자체를 넣는다. `for x in xs`, 집계의 항목, `xs.first`, `xs.last`, `xs[i]`는 값이다.
+ - `let xs: list of i64 = [1, 2, 3]`은 이벤트의 리스트를 그 값들로 시작한다. 리스트 리터럴은 거기에만 쓴다.
+- **자리로 읽고 쓰기.** 키 없는 리스트의 `xs[i]`(레코드의 리스트면 `xs[i].field`)는 i번째 항목이다. `xs[i] = 값`은 그것을 바꾼다.
+ 그 자리에 항목이 없으면 `not_found`다(Pure의 INDEX_AT. 끝에서 멈추는 `xs.first + i`와 다르다).
+- **`bytes(xs)`** 는 i64 리스트의 항목을 한 바이트씩 잇는다. 0–255 밖이면 `limit`이다.
+- **한 번에 주기.**
+ - `a, b = x, y`는 오른쪽을 모두 계산한 뒤 왼쪽에 한 번에 준다. 대상은 let과 수, bool, i64 상태다.
+ - `let a, b = x, y`는 let 여럿을 만든다.
+ - 줄은 쉼표 뒤에서 넘길 수 있다.
+
+검증:
+- 진단 12건: 수의 비트 연산, text나 수를 자리로 읽기, 잘못된 16진, i64 밖의 16진, 이름과 값의 수, 같은 이름 두 번, 한 번에 줄 수
+ 없는 상태, let에 text, 레코드 리스트의 `bytes`, 식 안의 리스트 리터럴.
+- 받아들이는 꼴 하나: 위의 모든 꼴과 보기의 인자, fn 매개변수의 바이트.
+- 무작위 비트 식 192개(파이썬의 정수와 i64의 넘침, 시프트 한도로) 사건 768개, 그중 실패 196개가 파이썬과 같다.
+- 바이트와 리스트의 앱이 파이썬과 같다(`limit`, `not_found` 포함).
+- `examples/sha256.aup`는 Pure의 검사가 FIPS 180-2의 예와 길이 0–129 등의 메시지로 `hashlib`와 대조한다(세 실행 길).