diff options
| author | eunhhu <[email protected]> | 2026-10-13 06:16:12 +0100 |
|---|---|---|
| committer | eunhhu <[email protected]> | 2026-10-13 06:16:12 +0100 |
| commit | 6209ddb42b953902828972b2e09f0296a51fe565 (patch) | |
| tree | 51be65e5831760c3d416f9ed1431f39dfd569e6a /examples | |
| parent | 557a69ef5102292eceb25f823ebcfc989810ab0c (diff) | |
| download | aup-6209ddb42b953902828972b2e09f0296a51fe565.tar.gz aup-6209ddb42b953902828972b2e09f0296a51fe565.zip | |
Formats, joins, slices, lets of bytes and text, while and && and || that decide alone (Pure 027's stage 2a): {v:08x}, {p:.2f} (Python's mini-language, [0][width][.digits][d x X b o f]), a + b of texts or of bytes, b[a .. c] of bytes and of texts (a cut inside a character failing as encoding), byte(n), let s = bytes or text (16 of each a handler, s = s + e appending in place), while c { } as a count to 2^53 that breaks when c is false, && and || computing their right side only where it decides (an AND or OR still where it cannot fail: comparisons, states and fields, a walked item's fields, a number plus a small literal, what the left side computed; every module of the apps and benchmarks byte for byte the same but json's); examples/json.aup, examples/sha256.aup in formats and joined bytes; 14 diagnostics, one accepted form, 144 random formats against Python's format() and an app cutting at commas
Diffstat (limited to 'examples')
| -rw-r--r-- | examples/json.aup | 84 | ||||
| -rw-r--r-- | examples/sha256.aup | 23 |
2 files changed, 90 insertions, 17 deletions
diff --git a/examples/json.aup b/examples/json.aup new file mode 100644 index 0000000..9e6faec --- /dev/null +++ b/examples/json.aup @@ -0,0 +1,84 @@ +# Whether a message's bytes are one JSON text (RFC 8259), read once from the start with a stack of the arrays and +# objects open. Input that is not UTF-8 fails as encoding: it is no JSON text either. +state valid = false +input check = message { data: bytes } + +fn space(b) = b == 0x20 || b == 0x09 || b == 0x0a || b == 0x0d +fn digit(b) = b >= 0x30 && b <= 0x39 +fn hex(b) = digit(b) || (b >= 0x61 && b <= 0x66) || (b >= 0x41 && b <= 0x46) + +on check { + let t = text(check.data) + let d = bytes(t) + let n, i, mode, ok = d.bytes, 0, 0, true # mode 0: a value, 1: after one, 2: a key, 3: a key or }, 4: a value or ] + let open: list of i64 + while ok { + while i < n && space(d[i]) { i = i + 1 } + if i == n { + ok = mode == 1 && open.count == 0 + break + } + let b = d[i] + if mode == 1 { + if open.count == 0 { ok = false } + else if b == 0x2c { mode = if open.last == 0x5b { 0 } else { 2 } } + else if b == open.last + 2 { open.remove(open.count - 1) } + else { ok = false } + i = i + 1 + } else if mode == 3 && b == 0x7d || mode == 4 && b == 0x5d { + open.remove(open.count - 1) + mode = 1 + i = i + 1 + } else if mode == 2 || mode == 3 { + if b != 0x22 { ok = false } + mode = 5 # the key, then ':' + } else if b == 0x5b || b == 0x7b { + open.append(b) + mode = if b == 0x5b { 4 } else { 3 } + i = i + 1 + } else if b == 0x22 || mode == 5 { + i = i + 1 # a string: no control bytes, escapes as RFC 8259 writes them + while i < n && d[i] != 0x22 && ok { + if d[i] < 0x20 { ok = false } + else if d[i] == 0x5c && i + 1 < n && d[i + 1] == 0x75 { + ok = i + 5 < n && hex(d[i + 2]) && hex(d[i + 3]) && hex(d[i + 4]) && hex(d[i + 5]) + i = i + 6 + } else if d[i] == 0x5c { + ok = i + 1 < n && (d[i + 1] == 0x22 || d[i + 1] == 0x5c || d[i + 1] == 0x2f || d[i + 1] == 0x62 || + d[i + 1] == 0x66 || d[i + 1] == 0x6e || d[i + 1] == 0x72 || d[i + 1] == 0x74) + i = i + 2 + } else { i = i + 1 } + } + ok = ok && i < n + i = i + 1 + if mode == 5 { + while i < n && space(d[i]) { i = i + 1 } + ok = ok && i < n && d[i] == 0x3a + i = i + 1 + mode = 0 + } else { mode = 1 } + } else if b == 0x2d || digit(b) { # -?(0|[1-9]\d*)(\.\d+)?([eE][+-]?\d+)? + if b == 0x2d { i = i + 1 } + ok = i < n && digit(d[i]) + if ok && d[i] == 0x30 { i = i + 1 } else { while i < n && digit(d[i]) { i = i + 1 } } + if ok && i < n && d[i] == 0x2e { + i = i + 1 + ok = i < n && digit(d[i]) + while i < n && digit(d[i]) { i = i + 1 } + } + if ok && i < n && (d[i] == 0x65 || d[i] == 0x45) { + i = i + 1 + if i < n && (d[i] == 0x2b || d[i] == 0x2d) { i = i + 1 } + ok = i < n && digit(d[i]) + while i < n && digit(d[i]) { i = i + 1 } + } + mode = 1 + } else { + let word = if b == 0x74 { "true" } else if b == 0x66 { "false" } else { "null" } + ok = i + word.bytes <= n && t[i .. i + word.bytes] == word + i = i + word.bytes + mode = 1 + } + } + valid = ok +} diff --git a/examples/sha256.aup b/examples/sha256.aup index 2558e55..8d00383 100644 --- a/examples/sha256.aup +++ b/examples/sha256.aup @@ -3,9 +3,6 @@ state digest: text input hash = message { data: bytes } fn rotr(x, n) = (x >> n | x << (32 - n)) & 0xffffffff -# The byte at j of the message padded to whole blocks: 0x80 after it, its length in bits in the last 8. -fn padded(data, size, total, j) = (if j < size { data[j] } else if j == size { 0x80 } - else if j >= total - 8 { i64(size) * 8 >> 8 * (total - 1 - j) & 0xff } else { 0 }) on hash { let k: list of i64 = [ @@ -22,13 +19,13 @@ on hash { 0x1f83d9ab, 0x5be0cd19 let w: list of i64 for t in 0 .. 64 { w.append(0) } - let size = hash.data.bytes - let total = (floor((size + 8) / 64) + 1) * 64 - for block in 0 .. total / 64 { + let m = hash.data + byte(0x80) # padded: 0x80, zeros, the length in bits in the last 8 bytes + while m.bytes % 64 != 56 { m = m + byte(0) } + for s in 0 .. 8 { m = m + byte(i64(hash.data.bytes) * 8 >> 56 - 8 * s & 0xff) } + for block in 0 .. m.bytes / 64 { for t in 0 .. 16 { let j = block * 64 + t * 4 - w[t] = (padded(hash.data, size, total, j) << 24 | padded(hash.data, size, total, j + 1) << 16 | - padded(hash.data, size, total, j + 2) << 8 | padded(hash.data, size, total, j + 3)) + w[t] = m[j] << 24 | m[j + 1] << 16 | m[j + 2] << 8 | m[j + 3] } for t in 16 .. 64 { let x = w[t - 15] @@ -44,13 +41,5 @@ on hash { h0, h1, h2, h3 = (h0 + a) & 0xffffffff, (h1 + b) & 0xffffffff, (h2 + c) & 0xffffffff, (h3 + d) & 0xffffffff h4, h5, h6, h7 = (h4 + e) & 0xffffffff, (h5 + f) & 0xffffffff, (h6 + g) & 0xffffffff, (h7 + hh) & 0xffffffff } - let h: list of i64 = [h0, h1, h2, h3, h4, h5, h6, h7] - let hex: list of i64 - for i in 0 .. 8 { - for s in 0 .. 8 { - let nibble = h[i] >> 28 - 4 * s & 0xf - hex.append(if nibble < 10 { 48 + nibble } else { 87 + nibble }) - } - } - digest = text(bytes(hex)) + digest = "{h0:08x}{h1:08x}{h2:08x}{h3:08x}{h4:08x}{h5:08x}{h6:08x}{h7:08x}" } |
