@hviana/sema 0.2.5 → 0.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/mind/attention.ts +355 -19
- package/test/53-cross-region-probe-instrumentation.test.mjs +356 -0
- package/dist/example/demo.d.ts +0 -1
- package/dist/example/demo.js +0 -39
- package/dist/example/train_base.d.ts +0 -87
- package/dist/example/train_base.js +0 -2252
- package/dist/src/alphabet.d.ts +0 -7
- package/dist/src/alphabet.js +0 -33
- package/dist/src/alu/src/alu.d.ts +0 -185
- package/dist/src/alu/src/alu.js +0 -440
- package/dist/src/alu/src/expr.d.ts +0 -61
- package/dist/src/alu/src/expr.js +0 -318
- package/dist/src/alu/src/index.d.ts +0 -11
- package/dist/src/alu/src/index.js +0 -19
- package/dist/src/alu/src/kernel-arith.d.ts +0 -16
- package/dist/src/alu/src/kernel-arith.js +0 -264
- package/dist/src/alu/src/kernel-bits.d.ts +0 -19
- package/dist/src/alu/src/kernel-bits.js +0 -152
- package/dist/src/alu/src/kernel-logic.d.ts +0 -4
- package/dist/src/alu/src/kernel-logic.js +0 -60
- package/dist/src/alu/src/kernel-nd.d.ts +0 -3
- package/dist/src/alu/src/kernel-nd.js +0 -208
- package/dist/src/alu/src/kernel-numeric.d.ts +0 -54
- package/dist/src/alu/src/kernel-numeric.js +0 -366
- package/dist/src/alu/src/operation.d.ts +0 -168
- package/dist/src/alu/src/operation.js +0 -189
- package/dist/src/alu/src/parser.d.ts +0 -221
- package/dist/src/alu/src/parser.js +0 -577
- package/dist/src/alu/src/resonance.d.ts +0 -55
- package/dist/src/alu/src/resonance.js +0 -126
- package/dist/src/alu/src/text.d.ts +0 -31
- package/dist/src/alu/src/text.js +0 -73
- package/dist/src/alu/src/value.d.ts +0 -109
- package/dist/src/alu/src/value.js +0 -300
- package/dist/src/alu/test/alu.test.d.ts +0 -1
- package/dist/src/alu/test/alu.test.js +0 -764
- package/dist/src/bytes.d.ts +0 -14
- package/dist/src/bytes.js +0 -59
- package/dist/src/canon.d.ts +0 -26
- package/dist/src/canon.js +0 -57
- package/dist/src/config.d.ts +0 -111
- package/dist/src/config.js +0 -91
- package/dist/src/derive/src/deduction.d.ts +0 -125
- package/dist/src/derive/src/deduction.js +0 -155
- package/dist/src/derive/src/index.d.ts +0 -7
- package/dist/src/derive/src/index.js +0 -11
- package/dist/src/derive/src/priority-queue.d.ts +0 -20
- package/dist/src/derive/src/priority-queue.js +0 -73
- package/dist/src/derive/src/rewrite.d.ts +0 -56
- package/dist/src/derive/src/rewrite.js +0 -100
- package/dist/src/derive/src/trie.d.ts +0 -90
- package/dist/src/derive/src/trie.js +0 -217
- package/dist/src/derive/test/derive.test.d.ts +0 -1
- package/dist/src/derive/test/derive.test.js +0 -122
- package/dist/src/extension.d.ts +0 -37
- package/dist/src/extension.js +0 -7
- package/dist/src/geometry.d.ts +0 -202
- package/dist/src/geometry.js +0 -575
- package/dist/src/index.d.ts +0 -16
- package/dist/src/index.js +0 -18
- package/dist/src/ingest-cache.d.ts +0 -41
- package/dist/src/ingest-cache.js +0 -161
- package/dist/src/mind/articulation.d.ts +0 -6
- package/dist/src/mind/articulation.js +0 -99
- package/dist/src/mind/attention.d.ts +0 -315
- package/dist/src/mind/attention.js +0 -1549
- package/dist/src/mind/bridge.d.ts +0 -30
- package/dist/src/mind/bridge.js +0 -569
- package/dist/src/mind/canonical.d.ts +0 -29
- package/dist/src/mind/canonical.js +0 -88
- package/dist/src/mind/graph-search.d.ts +0 -285
- package/dist/src/mind/graph-search.js +0 -956
- package/dist/src/mind/index.d.ts +0 -7
- package/dist/src/mind/index.js +0 -5
- package/dist/src/mind/junction.d.ts +0 -124
- package/dist/src/mind/junction.js +0 -317
- package/dist/src/mind/learning.d.ts +0 -47
- package/dist/src/mind/learning.js +0 -248
- package/dist/src/mind/match.d.ts +0 -126
- package/dist/src/mind/match.js +0 -441
- package/dist/src/mind/mechanisms/alu.d.ts +0 -4
- package/dist/src/mind/mechanisms/alu.js +0 -36
- package/dist/src/mind/mechanisms/cast.d.ts +0 -89
- package/dist/src/mind/mechanisms/cast.js +0 -716
- package/dist/src/mind/mechanisms/confluence.d.ts +0 -24
- package/dist/src/mind/mechanisms/confluence.js +0 -225
- package/dist/src/mind/mechanisms/cover.d.ts +0 -6
- package/dist/src/mind/mechanisms/cover.js +0 -203
- package/dist/src/mind/mechanisms/extraction.d.ts +0 -67
- package/dist/src/mind/mechanisms/extraction.js +0 -387
- package/dist/src/mind/mechanisms/recall.d.ts +0 -13
- package/dist/src/mind/mechanisms/recall.js +0 -325
- package/dist/src/mind/mind.d.ts +0 -276
- package/dist/src/mind/mind.js +0 -572
- package/dist/src/mind/pipeline-mechanism.d.ts +0 -142
- package/dist/src/mind/pipeline-mechanism.js +0 -213
- package/dist/src/mind/pipeline.d.ts +0 -20
- package/dist/src/mind/pipeline.js +0 -217
- package/dist/src/mind/primitives.d.ts +0 -70
- package/dist/src/mind/primitives.js +0 -287
- package/dist/src/mind/rationale.d.ts +0 -139
- package/dist/src/mind/rationale.js +0 -163
- package/dist/src/mind/reasoning.d.ts +0 -34
- package/dist/src/mind/reasoning.js +0 -240
- package/dist/src/mind/recognition.d.ts +0 -20
- package/dist/src/mind/recognition.js +0 -390
- package/dist/src/mind/resonance.d.ts +0 -23
- package/dist/src/mind/resonance.js +0 -0
- package/dist/src/mind/trace.d.ts +0 -15
- package/dist/src/mind/trace.js +0 -73
- package/dist/src/mind/traverse.d.ts +0 -113
- package/dist/src/mind/traverse.js +0 -568
- package/dist/src/mind/types.d.ts +0 -289
- package/dist/src/mind/types.js +0 -130
- package/dist/src/rabitq-ivf/src/database.d.ts +0 -113
- package/dist/src/rabitq-ivf/src/database.js +0 -201
- package/dist/src/rabitq-ivf/src/index.d.ts +0 -7
- package/dist/src/rabitq-ivf/src/index.js +0 -4
- package/dist/src/rabitq-ivf/src/ivf.d.ts +0 -200
- package/dist/src/rabitq-ivf/src/ivf.js +0 -1165
- package/dist/src/rabitq-ivf/src/prng.d.ts +0 -19
- package/dist/src/rabitq-ivf/src/prng.js +0 -36
- package/dist/src/rabitq-ivf/src/rabitq.d.ts +0 -95
- package/dist/src/rabitq-ivf/src/rabitq.js +0 -283
- package/dist/src/sema.d.ts +0 -31
- package/dist/src/sema.js +0 -63
- package/dist/src/store-sqlite.d.ts +0 -184
- package/dist/src/store-sqlite.js +0 -942
- package/dist/src/store.d.ts +0 -663
- package/dist/src/store.js +0 -1618
- package/dist/src/vec.d.ts +0 -31
- package/dist/src/vec.js +0 -109
|
@@ -1,126 +0,0 @@
|
|
|
1
|
-
// resonance.ts — ALU's window onto meaning, and how the host pre-resolves it.
|
|
2
|
-
//
|
|
3
|
-
// ALU computes on bytes of any modality, but WHICH operation a byte span invokes
|
|
4
|
-
// — and what the opposite of a symbol is — are questions of MEANING, and only
|
|
5
|
-
// resonance can read meaning from an opaque span. Two behaviours need it, and
|
|
6
|
-
// BOTH are generic (any operation, any modality), not special cases:
|
|
7
|
-
//
|
|
8
|
-
// • operation recognition — the operation a query asks for is, in general, NOT
|
|
9
|
-
// literally spelled. "2+2" carries a "+", but "the integral of …", "the
|
|
10
|
-
// limit as …", "the derivative of …", or the analogous request expressed as
|
|
11
|
-
// an image / audio gesture carry NO operator symbol at all. The operation
|
|
12
|
-
// must be recognised from the span's GIST resonating with the operation's
|
|
13
|
-
// CONCEPT. This is the primary, generic recognition path; the literal
|
|
14
|
-
// symbol scan (alu.ts `scan`) is merely the easy special case layered under
|
|
15
|
-
// it. Recognition is by gist, so it is modality-agnostic: a "+" drawn, a
|
|
16
|
-
// "plus" spoken, and the byte "+" all resonate toward the same `add`
|
|
17
|
-
// concept.
|
|
18
|
-
//
|
|
19
|
-
// • the polymorphic inverse — the opposite of a SYMBOL (the bytes of a learnt
|
|
20
|
-
// form, any modality) is its RESONANT opposite, found in the resonance
|
|
21
|
-
// space, not by arithmetic. The inverse of a number is its negation; the
|
|
22
|
-
// inverse of a form is its antonym/complement.
|
|
23
|
-
//
|
|
24
|
-
// Both are ASYNC in SEMA (they hit the gist / halo index), but the
|
|
25
|
-
// lightest-derivation search is SYNCHRONOUS. So — exactly as src/mind/pipeline.ts hoists
|
|
26
|
-
// concept hops and connectors into Maps before the search and reads them
|
|
27
|
-
// synchronously inside the rules — ALU splits each capability in two:
|
|
28
|
-
//
|
|
29
|
-
// AluResonance (async) — what the HOST implements over its resonance index.
|
|
30
|
-
// Called only during pre-resolution.
|
|
31
|
-
// ResonanceSync (sync) — the pre-resolved snapshot the op callbacks / rules
|
|
32
|
-
// read (ResonanceSync is declared in operation.ts).
|
|
33
|
-
//
|
|
34
|
-
// {@link prefetchOpposites} and {@link prefetchRecognisedOps} turn the async side
|
|
35
|
-
// into synchronous lookups for a known set of spans; the host calls them during
|
|
36
|
-
// its pre-resolution pass. This file is the ENTIRE coupling surface to SEMA —
|
|
37
|
-
// ALU imports nothing from the mind or store; the host supplies a AluResonance
|
|
38
|
-
// built over its own perception + resonance (gist nearness to the operation
|
|
39
|
-
// vocabulary ALU exposes via `conceptForms`, and halo resonance for the
|
|
40
|
-
// opposite).
|
|
41
|
-
import { latin1 } from "../../bytes.js";
|
|
42
|
-
/** A AluResonance that knows nothing — the default when the host wires none in,
|
|
43
|
-
* so the kernel runs fully decoupled (operations resolve by literal forms only,
|
|
44
|
-
* and a symbol inverse is left unchanged). */
|
|
45
|
-
export const NO_ALU_RESONANCE = {
|
|
46
|
-
recogniseOp: async () => null,
|
|
47
|
-
opposite: async () => null,
|
|
48
|
-
};
|
|
49
|
-
/** Pre-resolve the resonant opposite of each symbol in `symbols`, awaiting the
|
|
50
|
-
* host's async resonance once per distinct span, and return a SYNCHRONOUS
|
|
51
|
-
* snapshot the op callbacks read during the search. Keyed by the latin1 view
|
|
52
|
-
* of the bytes (a lossless, stable string key — the same device the search's
|
|
53
|
-
* chart uses). This is the async→sync bridge for the polymorphic inverse,
|
|
54
|
-
* mirroring how a concept hop's target is pre-resolved and read synchronously. */
|
|
55
|
-
export async function prefetchOpposites(resonance, symbols) {
|
|
56
|
-
const table = new Map();
|
|
57
|
-
const seen = new Set();
|
|
58
|
-
for (const bytes of symbols) {
|
|
59
|
-
const key = latin1(bytes);
|
|
60
|
-
if (seen.has(key))
|
|
61
|
-
continue;
|
|
62
|
-
seen.add(key);
|
|
63
|
-
const opp = await resonance.opposite(bytes);
|
|
64
|
-
if (opp)
|
|
65
|
-
table.set(key, opp);
|
|
66
|
-
}
|
|
67
|
-
return {
|
|
68
|
-
opposite: (bytes) => table.get(latin1(bytes)) ?? null,
|
|
69
|
-
// Opposites-only prefetch carries no op recognition; a higher-order nd op
|
|
70
|
-
// resolving through this falls back to literal forms / canonical names.
|
|
71
|
-
recogniseOp: () => null,
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
/** Pre-resolve BOTH capabilities a computation may need synchronously — the
|
|
75
|
-
* resonant opposite of a symbol (for the polymorphic inverse) AND the operation
|
|
76
|
-
* a symbol's MEANING names (for a higher-order nd op's function argument) — over
|
|
77
|
-
* one set of candidate spans, and return a single {@link ResonanceSync}. Each
|
|
78
|
-
* distinct span is awaited once per capability. This is the unified async→sync
|
|
79
|
-
* bridge the host uses for an nd computation, where the same spans may serve as
|
|
80
|
-
* inverse operands and as a reduce/map/filter operator. Either lookup yields
|
|
81
|
-
* null for a span that resonates with nothing, so callbacks decline rather than
|
|
82
|
-
* guess. */
|
|
83
|
-
export async function prefetchResonance(resonance, spans) {
|
|
84
|
-
const opposites = new Map();
|
|
85
|
-
const ops = new Map();
|
|
86
|
-
const seen = new Set();
|
|
87
|
-
for (const bytes of spans) {
|
|
88
|
-
const key = latin1(bytes);
|
|
89
|
-
if (seen.has(key))
|
|
90
|
-
continue;
|
|
91
|
-
seen.add(key);
|
|
92
|
-
const [opp, op] = await Promise.all([
|
|
93
|
-
resonance.opposite(bytes),
|
|
94
|
-
resonance.recogniseOp(bytes),
|
|
95
|
-
]);
|
|
96
|
-
if (opp)
|
|
97
|
-
opposites.set(key, opp);
|
|
98
|
-
if (op)
|
|
99
|
-
ops.set(key, op);
|
|
100
|
-
}
|
|
101
|
-
return {
|
|
102
|
-
opposite: (bytes) => opposites.get(latin1(bytes)) ?? null,
|
|
103
|
-
recogniseOp: (bytes) => ops.get(latin1(bytes)) ?? null,
|
|
104
|
-
};
|
|
105
|
-
}
|
|
106
|
-
/** Pre-resolve, for each candidate span, the operation its MEANING names —
|
|
107
|
-
* awaiting the host's async gist resonance once per distinct span — and return
|
|
108
|
-
* a synchronous map keyed by the span's latin1 bytes → canonical op name. This
|
|
109
|
-
* is the async→sync bridge for the GENERIC operation-recognition path: a span
|
|
110
|
-
* the literal scan could not classify (no operator symbol) but whose gist
|
|
111
|
-
* resonates with an operation's concept. Spans that resonate with nothing are
|
|
112
|
-
* omitted, so the caller treats a miss as "not an operation". */
|
|
113
|
-
export async function prefetchRecognisedOps(resonance, spans) {
|
|
114
|
-
const table = new Map();
|
|
115
|
-
const seen = new Set();
|
|
116
|
-
for (const bytes of spans) {
|
|
117
|
-
const key = latin1(bytes);
|
|
118
|
-
if (seen.has(key))
|
|
119
|
-
continue;
|
|
120
|
-
seen.add(key);
|
|
121
|
-
const op = await resonance.recogniseOp(bytes);
|
|
122
|
-
if (op)
|
|
123
|
-
table.set(key, op);
|
|
124
|
-
}
|
|
125
|
-
return table;
|
|
126
|
-
}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
/** An ASCII decimal digit. */
|
|
2
|
-
export declare const isDigitByte: (c: number) => boolean;
|
|
3
|
-
/** The decimal point of a numeral. */
|
|
4
|
-
export declare const DOT = 46;
|
|
5
|
-
/** The explicit list container's delimiters — the canonical nd spelling the
|
|
6
|
-
* codec emits, so a computed list feeds straight back in as an operand. */
|
|
7
|
-
export declare const OPEN = 91;
|
|
8
|
-
export declare const CLOSE = 93;
|
|
9
|
-
/** ASCII whitespace (space, tab, newline, carriage return) — the one spacing
|
|
10
|
-
* convention bytes of every textual modality share. */
|
|
11
|
-
export declare const isSpaceByte: (c: number) => boolean;
|
|
12
|
-
/** A byte that DELIMITS list elements inside an explicit container: whitespace,
|
|
13
|
-
* a comma, or a semicolon. Deliberately excludes anything that can sit inside
|
|
14
|
-
* a numeral or a symbol token (letters, digits, sign/decimal `+ - .`) and the
|
|
15
|
-
* brackets themselves, so an element's own bytes are never split. */
|
|
16
|
-
export declare const isSepByte: (c: number) => boolean;
|
|
17
|
-
/** The index of the first non-whitespace byte (or the length, if all space). */
|
|
18
|
-
export declare function trimStart(b: Uint8Array): number;
|
|
19
|
-
/** The index one past the last non-whitespace byte (or 0, if all space). */
|
|
20
|
-
export declare function trimEnd(b: Uint8Array): number;
|
|
21
|
-
/** The index of the `]` matching the `[` at `open`, bracket-depth aware, or -1
|
|
22
|
-
* when it is unbalanced — used to test whether a span is one explicit list
|
|
23
|
-
* CONTAINER (its opening bracket closing exactly at its end). */
|
|
24
|
-
export declare function matchBracket(b: Uint8Array, open: number): number;
|
|
25
|
-
/** The maximal non-whitespace runs of `bytes` within [from, to) — the spacing
|
|
26
|
-
* floor's reading of "the tokens", shared by the structural host's segmenter
|
|
27
|
-
* and the parser's term lexing so neither re-implements the walk. */
|
|
28
|
-
export declare function nonSpaceRuns(bytes: Uint8Array, from?: number, to?: number): Array<{
|
|
29
|
-
i: number;
|
|
30
|
-
j: number;
|
|
31
|
-
}>;
|
package/dist/src/alu/src/text.js
DELETED
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
// text.ts — the byte-class floor the ALU's lexing rests on.
|
|
2
|
-
//
|
|
3
|
-
// SEMA is byte-native and multimodal; the ALU keeps its knowledge of raw text
|
|
4
|
-
// as small as possible. What remains is the IRREDUCIBLE floor — the decimal
|
|
5
|
-
// numeral grammar (digits ground a quantity exactly as the byte alphabet
|
|
6
|
-
// grounds a symbol), whitespace as the universal spacing byte, and the list
|
|
7
|
-
// grammar's delimiters — collected HERE, once, so no other module hardcodes a
|
|
8
|
-
// character class of its own. Everything above this floor (which spans name
|
|
9
|
-
// operations, where terms begin and end, what an expression means) is resolved
|
|
10
|
-
// from the operation registry, the host's geometric segmentation, or resonance.
|
|
11
|
-
/** An ASCII decimal digit. */
|
|
12
|
-
export const isDigitByte = (c) => c >= 0x30 && c <= 0x39;
|
|
13
|
-
/** The decimal point of a numeral. */
|
|
14
|
-
export const DOT = 0x2e; // "."
|
|
15
|
-
/** The explicit list container's delimiters — the canonical nd spelling the
|
|
16
|
-
* codec emits, so a computed list feeds straight back in as an operand. */
|
|
17
|
-
export const OPEN = 0x5b; // "["
|
|
18
|
-
export const CLOSE = 0x5d; // "]"
|
|
19
|
-
/** ASCII whitespace (space, tab, newline, carriage return) — the one spacing
|
|
20
|
-
* convention bytes of every textual modality share. */
|
|
21
|
-
export const isSpaceByte = (c) => c === 0x20 || c === 0x09 || c === 0x0a || c === 0x0d;
|
|
22
|
-
/** A byte that DELIMITS list elements inside an explicit container: whitespace,
|
|
23
|
-
* a comma, or a semicolon. Deliberately excludes anything that can sit inside
|
|
24
|
-
* a numeral or a symbol token (letters, digits, sign/decimal `+ - .`) and the
|
|
25
|
-
* brackets themselves, so an element's own bytes are never split. */
|
|
26
|
-
export const isSepByte = (c) => isSpaceByte(c) || c === 0x2c /* , */ || c === 0x3b /* ; */;
|
|
27
|
-
/** The index of the first non-whitespace byte (or the length, if all space). */
|
|
28
|
-
export function trimStart(b) {
|
|
29
|
-
let i = 0;
|
|
30
|
-
while (i < b.length && isSpaceByte(b[i]))
|
|
31
|
-
i++;
|
|
32
|
-
return i;
|
|
33
|
-
}
|
|
34
|
-
/** The index one past the last non-whitespace byte (or 0, if all space). */
|
|
35
|
-
export function trimEnd(b) {
|
|
36
|
-
let j = b.length;
|
|
37
|
-
const lo = trimStart(b);
|
|
38
|
-
while (j > lo && isSpaceByte(b[j - 1]))
|
|
39
|
-
j--;
|
|
40
|
-
return j;
|
|
41
|
-
}
|
|
42
|
-
/** The index of the `]` matching the `[` at `open`, bracket-depth aware, or -1
|
|
43
|
-
* when it is unbalanced — used to test whether a span is one explicit list
|
|
44
|
-
* CONTAINER (its opening bracket closing exactly at its end). */
|
|
45
|
-
export function matchBracket(b, open) {
|
|
46
|
-
let depth = 0;
|
|
47
|
-
for (let i = open; i < b.length; i++) {
|
|
48
|
-
if (b[i] === OPEN)
|
|
49
|
-
depth++;
|
|
50
|
-
else if (b[i] === CLOSE && --depth === 0)
|
|
51
|
-
return i;
|
|
52
|
-
}
|
|
53
|
-
return -1;
|
|
54
|
-
}
|
|
55
|
-
/** The maximal non-whitespace runs of `bytes` within [from, to) — the spacing
|
|
56
|
-
* floor's reading of "the tokens", shared by the structural host's segmenter
|
|
57
|
-
* and the parser's term lexing so neither re-implements the walk. */
|
|
58
|
-
export function nonSpaceRuns(bytes, from = 0, to = bytes.length) {
|
|
59
|
-
const out = [];
|
|
60
|
-
let i = from;
|
|
61
|
-
while (i < to) {
|
|
62
|
-
if (isSpaceByte(bytes[i])) {
|
|
63
|
-
i++;
|
|
64
|
-
continue;
|
|
65
|
-
}
|
|
66
|
-
let j = i;
|
|
67
|
-
while (j < to && !isSpaceByte(bytes[j]))
|
|
68
|
-
j++;
|
|
69
|
-
out.push({ i, j });
|
|
70
|
-
i = j;
|
|
71
|
-
}
|
|
72
|
-
return out;
|
|
73
|
-
}
|
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
/** Which stratum a {@link Value} belongs to. Four scalar domains + the
|
|
2
|
-
* recursive container `nd`. */
|
|
3
|
-
export type Domain = "bit" | "int" | "real" | "symbol" | "nd";
|
|
4
|
-
/** A quantity the ALU computes on — a tagged union over the scalar domains plus
|
|
5
|
-
* the recursive n-dimensional container. An `nd`'s `items` are themselves
|
|
6
|
-
* Values of any domain, so nesting (a matrix = an nd of nd) and heterogeneity
|
|
7
|
-
* (a list mixing numbers, symbols, sub-lists) are the same case. */
|
|
8
|
-
export type Value = {
|
|
9
|
-
domain: "bit";
|
|
10
|
-
b: 0 | 1;
|
|
11
|
-
} | {
|
|
12
|
-
domain: "int";
|
|
13
|
-
n: bigint;
|
|
14
|
-
} | {
|
|
15
|
-
domain: "real";
|
|
16
|
-
x: number;
|
|
17
|
-
} | {
|
|
18
|
-
domain: "symbol";
|
|
19
|
-
bytes: Uint8Array;
|
|
20
|
-
} | {
|
|
21
|
-
domain: "nd";
|
|
22
|
-
items: Value[];
|
|
23
|
-
};
|
|
24
|
-
export declare const bit: (b: 0 | 1) => Value;
|
|
25
|
-
export declare const int: (n: bigint) => Value;
|
|
26
|
-
export declare const real: (x: number) => Value;
|
|
27
|
-
/** A symbolic value: an opaque byte span of any modality (see module note). */
|
|
28
|
-
export declare const symbol: (bytes: Uint8Array) => Value;
|
|
29
|
-
/** An n-dimensional value: an ordered list of element values (each any domain,
|
|
30
|
-
* including a nested nd). See the module note on nd. */
|
|
31
|
-
export declare const nd: (items: Value[]) => Value;
|
|
32
|
-
/** The domain tag of a value. */
|
|
33
|
-
export declare const tagOf: (v: Value) => Domain;
|
|
34
|
-
/** Whether a value is a numeric SCALAR (bit, int, or real) — an nd is not, even
|
|
35
|
-
* if every element is numeric (it is a container; reduce it to a scalar). */
|
|
36
|
-
export declare function isNumeric(v: Value): boolean;
|
|
37
|
-
/** Whether a value is the n-dimensional container. */
|
|
38
|
-
export declare function isNd(v: Value): v is {
|
|
39
|
-
domain: "nd";
|
|
40
|
-
items: Value[];
|
|
41
|
-
};
|
|
42
|
-
/** Collect, into `out`, every SYMBOL byte span reachable inside a value — itself
|
|
43
|
-
* when it is a symbol, or each element recursively when it is an nd. These are
|
|
44
|
-
* the spans whose MEANING (a resonant opposite, the operation a higher-order op
|
|
45
|
-
* argument names) the host pre-resolves before a computation; numbers carry no
|
|
46
|
-
* meaning to resolve, so they are skipped. */
|
|
47
|
-
export declare function symbolSpans(v: Value, out: Uint8Array[]): void;
|
|
48
|
-
/** A value as a JS number — bit→0|1, int→Number, real as-is. Throws on a
|
|
49
|
-
* symbol, because arithmetic on an opaque form is a programming error the
|
|
50
|
-
* caller (or the graph adapter's try/catch) should surface, never silently
|
|
51
|
-
* coerce to NaN. */
|
|
52
|
-
export declare function asReal(v: Value): number;
|
|
53
|
-
/** A value as an exact bigint — real is truncated toward zero (a real that is
|
|
54
|
-
* not integral loses its fraction; callers wanting exactness keep it int). */
|
|
55
|
-
export declare function asInt(v: Value): bigint;
|
|
56
|
-
/** A value as a logic bit — nonzero numbers read as 1, zero as 0. Throws on a
|
|
57
|
-
* symbol (an opaque form is not a truth value). */
|
|
58
|
-
export declare function asBit(v: Value): 0 | 1;
|
|
59
|
-
/** Promote a value into a target numeric domain (bit ⊂ int ⊂ real). Used when
|
|
60
|
-
* a mixed-domain expression must agree on one domain before a primitive runs —
|
|
61
|
-
* the rule is the natural lattice: any real operand pulls the whole expression
|
|
62
|
-
* to real, otherwise any int pulls it to int, otherwise bit. */
|
|
63
|
-
export declare function coerce(v: Value, domain: "bit" | "int" | "real"): Value;
|
|
64
|
-
/** The common numeric domain of a list of operands, by the bit ⊂ int ⊂ real
|
|
65
|
-
* lattice: real if any operand is real, else int if any is int, else bit.
|
|
66
|
-
* Throws if any operand is a symbol. This is how a polymorphic arithmetic op
|
|
67
|
-
* decides whether to take the exact bigint path or the native-double path. */
|
|
68
|
-
export declare function joinDomain(args: Value[]): "bit" | "int" | "real";
|
|
69
|
-
/** The host's bridge between byte spans and values. ALU emits and consumes
|
|
70
|
-
* bytes only through this, so the surrounding system owns how a number is
|
|
71
|
-
* spelled. A default ({@link decimalCodec}) is provided. */
|
|
72
|
-
export interface ValueCodec {
|
|
73
|
-
encode(v: Value): Uint8Array;
|
|
74
|
-
decode(bytes: Uint8Array): Value | null;
|
|
75
|
-
}
|
|
76
|
-
/** Parse a byte span into a SCALAR value: a clean integer numeral → exact int, a
|
|
77
|
-
* fractional/exponent numeral → real, anything else → a symbol carrying its
|
|
78
|
-
* bytes verbatim for the polymorphic inverse.
|
|
79
|
-
*
|
|
80
|
-
* This is the IRREDUCIBLE FLOOR — and the ONLY structure read at the value
|
|
81
|
-
* model's base: a number-form's digits ground a quantity, the exact analogue of
|
|
82
|
-
* the byte alphabet grounding a symbol. It does NOT read n-dimensional
|
|
83
|
-
* STRUCTURE (no bracket/comma grammar); recognising a list — a run of element
|
|
84
|
-
* values joined by a consistent separator — is layered ONE level up, in the
|
|
85
|
-
* facade's {@link "./alu.js".Alu.recogniseValue} (over the operand scanner),
|
|
86
|
-
* which calls this for each element. So the codec's `decode` (which delegates
|
|
87
|
-
* here) is scalar-only: a bracket literal decodes to an opaque symbol.
|
|
88
|
-
*
|
|
89
|
-
* Numerals are ASCII by construction; for any other byte content the bytes are
|
|
90
|
-
* preserved opaquely, so a symbol of any modality round-trips untouched. */
|
|
91
|
-
export declare function parseValue(bytes: Uint8Array): Value;
|
|
92
|
-
/** Canonically format a real as a decimal string: round to `precision` places,
|
|
93
|
-
* then trim trailing zeros (and a bare trailing point), normalising -0 to 0.
|
|
94
|
-
* Determinism here is load-bearing — the search keys an output span by its
|
|
95
|
-
* bytes, so two derivations of the same number MUST spell it identically. */
|
|
96
|
-
export declare function formatReal(x: number, precision: number): string;
|
|
97
|
-
/** The default codec: integers as exact decimals, reals canonically formatted,
|
|
98
|
-
* bits as "0"/"1", symbols as their own bytes (verbatim, any modality), and an
|
|
99
|
-
* nd as a bracket literal `[e0,e1,…]` of its element encodings (recursive, so a
|
|
100
|
-
* nested list nests its brackets and a symbol element keeps its raw bytes).
|
|
101
|
-
* `precision` controls real rounding (see {@link formatReal}).
|
|
102
|
-
*
|
|
103
|
-
* The bracket layout is the CANONICAL OUTPUT spelling of an `nd` — one
|
|
104
|
-
* deterministic form, the analogue of decimal for a number, so the search's
|
|
105
|
-
* chart memoises identical results identically. It is an ENCODE-only grammar:
|
|
106
|
-
* {@link parseValue} (hence `decode`) reads only scalars, never structure — a
|
|
107
|
-
* bracket literal decodes back to an opaque symbol. Reading list STRUCTURE from
|
|
108
|
-
* bytes is layered one level up, in {@link "./alu.js".Alu.recogniseValue}. */
|
|
109
|
-
export declare function decimalCodec(precision: number): ValueCodec;
|
|
@@ -1,300 +0,0 @@
|
|
|
1
|
-
// value.ts — the ALU value model.
|
|
2
|
-
//
|
|
3
|
-
// One tagged union carries every kind of quantity the ALU computes on, so a
|
|
4
|
-
// single Operation registry can dispatch on the tag rather than maintaining
|
|
5
|
-
// disjoint kernels. The four domains are exactly the strata the kernel needs:
|
|
6
|
-
//
|
|
7
|
-
// • bit — a logic value 0|1. The completeness layer (nand and the gates
|
|
8
|
-
// derived from it) lives here.
|
|
9
|
-
// • int — an EXACT integer (JS bigint). The "everything derives from nand"
|
|
10
|
-
// bootstrap runs here: add is a ripple of full_adders, multiply is
|
|
11
|
-
// shift-add, and so on. bigint keeps the proof exact past 2^53.
|
|
12
|
-
// • real — an IEEE double. The limit layer (converge, exp, sin, …) is
|
|
13
|
-
// intrinsically continuous, so it runs on the host's native reals
|
|
14
|
-
// rather than a fixed-point reimplementation atop bits.
|
|
15
|
-
// • symbol — a raw BYTE SPAN that is not a number. SEMA is byte-native and
|
|
16
|
-
// multimodal: a symbol's bytes may name a written form, a region of
|
|
17
|
-
// an image, a fragment of audio — any learned form, in any
|
|
18
|
-
// modality. ALU never interprets those bytes; it treats a symbol
|
|
19
|
-
// as an opaque token. This is the carrier for the POLYMORPHIC
|
|
20
|
-
// inverse: the inverse of a number is its negation, but the inverse
|
|
21
|
-
// of a symbol is its RESONANT OPPOSITE — found in the resonance
|
|
22
|
-
// space, not by arithmetic (e.g. the bytes of "large" resolve to
|
|
23
|
-
// "small", but the mechanism is modality-agnostic — see
|
|
24
|
-
// resonance.ts). Resonance is the only thing that can read meaning
|
|
25
|
-
// from a symbol, and ALU reaches it only through an injected
|
|
26
|
-
// capability, never directly.
|
|
27
|
-
//
|
|
28
|
-
// • nd — an N-DIMENSIONAL value: an ordered list of elements, each of which
|
|
29
|
-
// is ITSELF a Value of ANY domain — a scalar (bit/int/real/symbol)
|
|
30
|
-
// OR another nd. So nd is recursive (a tensor is an nd of nds), it
|
|
31
|
-
// is RAGGED (rows need not be equal length — it is a list, not a
|
|
32
|
-
// rectangular array), and it is HETEROGENEOUS (a row may mix a
|
|
33
|
-
// number, a symbol, and a sub-list). This one recursive case is the
|
|
34
|
-
// whole generalisation: there is no separate "vector" vs "matrix"
|
|
35
|
-
// type, only nd nesting, and the rank is read off the nesting depth.
|
|
36
|
-
// Every scalar operation lifts over it automatically (broadcast, see
|
|
37
|
-
// operation.ts), and the structural operations (the nd kernel) build
|
|
38
|
-
// the list-processing layer — map/reduce/filter/find/… — on a tiny
|
|
39
|
-
// core of nd/length/at, exactly as logic builds on nand.
|
|
40
|
-
//
|
|
41
|
-
// The module is pure: it knows nothing of SEMA, the store, or the search. The
|
|
42
|
-
// only host coupling is the injected ValueCodec, whose default lives here.
|
|
43
|
-
// ── constructors ──────────────────────────────────────────────────────────
|
|
44
|
-
export const bit = (b) => ({ domain: "bit", b });
|
|
45
|
-
export const int = (n) => ({ domain: "int", n });
|
|
46
|
-
export const real = (x) => ({ domain: "real", x });
|
|
47
|
-
/** A symbolic value: an opaque byte span of any modality (see module note). */
|
|
48
|
-
export const symbol = (bytes) => ({
|
|
49
|
-
domain: "symbol",
|
|
50
|
-
bytes,
|
|
51
|
-
});
|
|
52
|
-
/** An n-dimensional value: an ordered list of element values (each any domain,
|
|
53
|
-
* including a nested nd). See the module note on nd. */
|
|
54
|
-
export const nd = (items) => ({ domain: "nd", items });
|
|
55
|
-
/** The domain tag of a value. */
|
|
56
|
-
export const tagOf = (v) => v.domain;
|
|
57
|
-
/** Whether a value is a numeric SCALAR (bit, int, or real) — an nd is not, even
|
|
58
|
-
* if every element is numeric (it is a container; reduce it to a scalar). */
|
|
59
|
-
export function isNumeric(v) {
|
|
60
|
-
return v.domain === "bit" || v.domain === "int" || v.domain === "real";
|
|
61
|
-
}
|
|
62
|
-
/** Whether a value is the n-dimensional container. */
|
|
63
|
-
export function isNd(v) {
|
|
64
|
-
return v.domain === "nd";
|
|
65
|
-
}
|
|
66
|
-
/** Collect, into `out`, every SYMBOL byte span reachable inside a value — itself
|
|
67
|
-
* when it is a symbol, or each element recursively when it is an nd. These are
|
|
68
|
-
* the spans whose MEANING (a resonant opposite, the operation a higher-order op
|
|
69
|
-
* argument names) the host pre-resolves before a computation; numbers carry no
|
|
70
|
-
* meaning to resolve, so they are skipped. */
|
|
71
|
-
export function symbolSpans(v, out) {
|
|
72
|
-
if (v.domain === "symbol")
|
|
73
|
-
out.push(v.bytes);
|
|
74
|
-
else if (isNd(v)) {
|
|
75
|
-
for (const e of v.items)
|
|
76
|
-
symbolSpans(e, out);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
// ── coercions (the functor's object map between domains) ────────────────────
|
|
80
|
-
/** A value as a JS number — bit→0|1, int→Number, real as-is. Throws on a
|
|
81
|
-
* symbol, because arithmetic on an opaque form is a programming error the
|
|
82
|
-
* caller (or the graph adapter's try/catch) should surface, never silently
|
|
83
|
-
* coerce to NaN. */
|
|
84
|
-
export function asReal(v) {
|
|
85
|
-
switch (v.domain) {
|
|
86
|
-
case "bit":
|
|
87
|
-
return v.b;
|
|
88
|
-
case "int":
|
|
89
|
-
return Number(v.n);
|
|
90
|
-
case "real":
|
|
91
|
-
return v.x;
|
|
92
|
-
case "symbol":
|
|
93
|
-
throw new TypeError("asReal: a symbol value has no numeric reading");
|
|
94
|
-
case "nd":
|
|
95
|
-
// An nd has no scalar reading: a scalar primitive never sees one, because
|
|
96
|
-
// broadcast (operation.ts) lifts it element-wise first. Reaching here
|
|
97
|
-
// means a structural op was mis-called on a list as if it were a scalar.
|
|
98
|
-
throw new TypeError("asReal: an nd value has no scalar numeric reading");
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
/** A value as an exact bigint — real is truncated toward zero (a real that is
|
|
102
|
-
* not integral loses its fraction; callers wanting exactness keep it int). */
|
|
103
|
-
export function asInt(v) {
|
|
104
|
-
switch (v.domain) {
|
|
105
|
-
case "bit":
|
|
106
|
-
return BigInt(v.b);
|
|
107
|
-
case "int":
|
|
108
|
-
return v.n;
|
|
109
|
-
case "real":
|
|
110
|
-
return BigInt(Math.trunc(v.x));
|
|
111
|
-
case "symbol":
|
|
112
|
-
throw new TypeError("asInt: a symbol value has no integer reading");
|
|
113
|
-
case "nd":
|
|
114
|
-
throw new TypeError("asInt: an nd value has no scalar integer reading");
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
/** A value as a logic bit — nonzero numbers read as 1, zero as 0. Throws on a
|
|
118
|
-
* symbol (an opaque form is not a truth value). */
|
|
119
|
-
export function asBit(v) {
|
|
120
|
-
switch (v.domain) {
|
|
121
|
-
case "bit":
|
|
122
|
-
return v.b;
|
|
123
|
-
case "int":
|
|
124
|
-
return v.n === 0n ? 0 : 1;
|
|
125
|
-
case "real":
|
|
126
|
-
return v.x === 0 ? 0 : 1;
|
|
127
|
-
case "symbol":
|
|
128
|
-
throw new TypeError("asBit: a symbol value is not a truth value");
|
|
129
|
-
case "nd":
|
|
130
|
-
throw new TypeError("asBit: an nd value is not a scalar truth value");
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
/** Promote a value into a target numeric domain (bit ⊂ int ⊂ real). Used when
|
|
134
|
-
* a mixed-domain expression must agree on one domain before a primitive runs —
|
|
135
|
-
* the rule is the natural lattice: any real operand pulls the whole expression
|
|
136
|
-
* to real, otherwise any int pulls it to int, otherwise bit. */
|
|
137
|
-
export function coerce(v, domain) {
|
|
138
|
-
if (v.domain === domain)
|
|
139
|
-
return v;
|
|
140
|
-
switch (domain) {
|
|
141
|
-
case "bit":
|
|
142
|
-
return bit(asBit(v));
|
|
143
|
-
case "int":
|
|
144
|
-
return int(asInt(v));
|
|
145
|
-
case "real":
|
|
146
|
-
return real(asReal(v));
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
/** The common numeric domain of a list of operands, by the bit ⊂ int ⊂ real
|
|
150
|
-
* lattice: real if any operand is real, else int if any is int, else bit.
|
|
151
|
-
* Throws if any operand is a symbol. This is how a polymorphic arithmetic op
|
|
152
|
-
* decides whether to take the exact bigint path or the native-double path. */
|
|
153
|
-
export function joinDomain(args) {
|
|
154
|
-
let d = "bit";
|
|
155
|
-
for (const a of args) {
|
|
156
|
-
if (a.domain === "symbol") {
|
|
157
|
-
throw new TypeError("joinDomain: cannot join a symbol value numerically");
|
|
158
|
-
}
|
|
159
|
-
if (a.domain === "nd") {
|
|
160
|
-
throw new TypeError("joinDomain: cannot join an nd value numerically");
|
|
161
|
-
}
|
|
162
|
-
if (a.domain === "real")
|
|
163
|
-
return "real";
|
|
164
|
-
if (a.domain === "int" && d === "bit")
|
|
165
|
-
d = "int";
|
|
166
|
-
}
|
|
167
|
-
return d;
|
|
168
|
-
}
|
|
169
|
-
const ASCII = {
|
|
170
|
-
decode: (b) => {
|
|
171
|
-
let s = "";
|
|
172
|
-
for (let i = 0; i < b.length; i++)
|
|
173
|
-
s += String.fromCharCode(b[i]);
|
|
174
|
-
return s;
|
|
175
|
-
},
|
|
176
|
-
encode: (s) => {
|
|
177
|
-
const out = new Uint8Array(s.length);
|
|
178
|
-
for (let i = 0; i < s.length; i++)
|
|
179
|
-
out[i] = s.charCodeAt(i) & 0xff;
|
|
180
|
-
return out;
|
|
181
|
-
},
|
|
182
|
-
};
|
|
183
|
-
/** A decimal numeral, sign, optional fraction, optional exponent — the syntax
|
|
184
|
-
* {@link parseScalar} accepts as a number. Anything else is a symbol. */
|
|
185
|
-
const NUMERAL = /^[+-]?(?:\d+\.?\d*|\.\d+)(?:[eE][+-]?\d+)?$/;
|
|
186
|
-
/** Concatenate byte arrays — used to build an nd literal's encoding without
|
|
187
|
-
* routing a (possibly non-ASCII, multimodal) symbol's bytes through a string. */
|
|
188
|
-
function concatBytes(arrs) {
|
|
189
|
-
let len = 0;
|
|
190
|
-
for (const a of arrs)
|
|
191
|
-
len += a.length;
|
|
192
|
-
const out = new Uint8Array(len);
|
|
193
|
-
let o = 0;
|
|
194
|
-
for (const a of arrs) {
|
|
195
|
-
out.set(a, o);
|
|
196
|
-
o += a.length;
|
|
197
|
-
}
|
|
198
|
-
return out;
|
|
199
|
-
}
|
|
200
|
-
/** Parse a SCALAR span: a clean integer numeral → exact int, a fractional/
|
|
201
|
-
* exponent numeral → real, anything else → a symbol carrying `bytes` verbatim.
|
|
202
|
-
* Strict, so it never hijacks a form that merely begins with a digit. */
|
|
203
|
-
function parseScalar(bytes, s) {
|
|
204
|
-
if (s.length > 0 && NUMERAL.test(s)) {
|
|
205
|
-
if (/[.eE]/.test(s)) {
|
|
206
|
-
const x = Number(s);
|
|
207
|
-
if (Number.isFinite(x))
|
|
208
|
-
return real(x);
|
|
209
|
-
}
|
|
210
|
-
else {
|
|
211
|
-
// A clean integer: strip a leading '+' that BigInt rejects.
|
|
212
|
-
try {
|
|
213
|
-
return int(BigInt(s[0] === "+" ? s.slice(1) : s));
|
|
214
|
-
}
|
|
215
|
-
catch {
|
|
216
|
-
/* fall through to symbol */
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
return symbol(bytes);
|
|
221
|
-
}
|
|
222
|
-
/** Parse a byte span into a SCALAR value: a clean integer numeral → exact int, a
|
|
223
|
-
* fractional/exponent numeral → real, anything else → a symbol carrying its
|
|
224
|
-
* bytes verbatim for the polymorphic inverse.
|
|
225
|
-
*
|
|
226
|
-
* This is the IRREDUCIBLE FLOOR — and the ONLY structure read at the value
|
|
227
|
-
* model's base: a number-form's digits ground a quantity, the exact analogue of
|
|
228
|
-
* the byte alphabet grounding a symbol. It does NOT read n-dimensional
|
|
229
|
-
* STRUCTURE (no bracket/comma grammar); recognising a list — a run of element
|
|
230
|
-
* values joined by a consistent separator — is layered ONE level up, in the
|
|
231
|
-
* facade's {@link "./alu.js".Alu.recogniseValue} (over the operand scanner),
|
|
232
|
-
* which calls this for each element. So the codec's `decode` (which delegates
|
|
233
|
-
* here) is scalar-only: a bracket literal decodes to an opaque symbol.
|
|
234
|
-
*
|
|
235
|
-
* Numerals are ASCII by construction; for any other byte content the bytes are
|
|
236
|
-
* preserved opaquely, so a symbol of any modality round-trips untouched. */
|
|
237
|
-
export function parseValue(bytes) {
|
|
238
|
-
return parseScalar(bytes, ASCII.decode(bytes));
|
|
239
|
-
}
|
|
240
|
-
/** Canonically format a real as a decimal string: round to `precision` places,
|
|
241
|
-
* then trim trailing zeros (and a bare trailing point), normalising -0 to 0.
|
|
242
|
-
* Determinism here is load-bearing — the search keys an output span by its
|
|
243
|
-
* bytes, so two derivations of the same number MUST spell it identically. */
|
|
244
|
-
export function formatReal(x, precision) {
|
|
245
|
-
if (!Number.isFinite(x))
|
|
246
|
-
return String(x); // "Infinity" / "NaN" / "-Infinity"
|
|
247
|
-
let s = x.toFixed(precision);
|
|
248
|
-
if (s.indexOf(".") >= 0)
|
|
249
|
-
s = s.replace(/\.?0+$/, "");
|
|
250
|
-
if (s === "-0" || s === "")
|
|
251
|
-
s = "0";
|
|
252
|
-
return s;
|
|
253
|
-
}
|
|
254
|
-
/** The default codec: integers as exact decimals, reals canonically formatted,
|
|
255
|
-
* bits as "0"/"1", symbols as their own bytes (verbatim, any modality), and an
|
|
256
|
-
* nd as a bracket literal `[e0,e1,…]` of its element encodings (recursive, so a
|
|
257
|
-
* nested list nests its brackets and a symbol element keeps its raw bytes).
|
|
258
|
-
* `precision` controls real rounding (see {@link formatReal}).
|
|
259
|
-
*
|
|
260
|
-
* The bracket layout is the CANONICAL OUTPUT spelling of an `nd` — one
|
|
261
|
-
* deterministic form, the analogue of decimal for a number, so the search's
|
|
262
|
-
* chart memoises identical results identically. It is an ENCODE-only grammar:
|
|
263
|
-
* {@link parseValue} (hence `decode`) reads only scalars, never structure — a
|
|
264
|
-
* bracket literal decodes back to an opaque symbol. Reading list STRUCTURE from
|
|
265
|
-
* bytes is layered one level up, in {@link "./alu.js".Alu.recogniseValue}. */
|
|
266
|
-
export function decimalCodec(precision) {
|
|
267
|
-
const enc = (v) => {
|
|
268
|
-
switch (v.domain) {
|
|
269
|
-
case "bit":
|
|
270
|
-
return ASCII.encode(String(v.b));
|
|
271
|
-
case "int":
|
|
272
|
-
return ASCII.encode(v.n.toString());
|
|
273
|
-
case "real":
|
|
274
|
-
return ASCII.encode(formatReal(v.x, precision));
|
|
275
|
-
case "symbol":
|
|
276
|
-
return v.bytes;
|
|
277
|
-
case "nd": {
|
|
278
|
-
// [e0,e1,…] at the byte level, so a symbol element's arbitrary
|
|
279
|
-
// (possibly non-ASCII / multimodal) bytes pass through untouched.
|
|
280
|
-
const OPEN = ASCII.encode("[");
|
|
281
|
-
const CLOSE = ASCII.encode("]");
|
|
282
|
-
const COMMA = ASCII.encode(",");
|
|
283
|
-
const parts = [OPEN];
|
|
284
|
-
for (let i = 0; i < v.items.length; i++) {
|
|
285
|
-
if (i > 0)
|
|
286
|
-
parts.push(COMMA);
|
|
287
|
-
parts.push(enc(v.items[i]));
|
|
288
|
-
}
|
|
289
|
-
parts.push(CLOSE);
|
|
290
|
-
return concatBytes(parts);
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
};
|
|
294
|
-
return {
|
|
295
|
-
encode: enc,
|
|
296
|
-
decode(bytes) {
|
|
297
|
-
return parseValue(bytes);
|
|
298
|
-
},
|
|
299
|
-
};
|
|
300
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|