@kalada/syntax 0.1.0
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/README.md +98 -0
- package/dist/index.cjs +2027 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +231 -0
- package/dist/index.d.ts +231 -0
- package/dist/index.js +2017 -0
- package/dist/index.js.map +1 -0
- package/package.json +47 -0
package/README.md
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# `@kalada/syntax`
|
|
2
|
+
|
|
3
|
+
Dependency-light, browser-safe source tooling for Kalada v1 expressions. The package provides a
|
|
4
|
+
lossless token stream and typed CST, deterministic diagnostics and formatting, and lowering to the
|
|
5
|
+
canonical `@kalada/core` program contract.
|
|
6
|
+
|
|
7
|
+
```ts
|
|
8
|
+
import {
|
|
9
|
+
formatKaladaV1Expression,
|
|
10
|
+
lowerKaladaV1Expression,
|
|
11
|
+
parseKaladaV1Expression,
|
|
12
|
+
} from "@kalada/syntax";
|
|
13
|
+
|
|
14
|
+
const parsed = parseKaladaV1Expression("price * quantity");
|
|
15
|
+
const lowered = lowerKaladaV1Expression(parsed, {
|
|
16
|
+
references: {
|
|
17
|
+
price: { reference: "price", type: { kind: "primitive-type", name: "number" } },
|
|
18
|
+
quantity: { reference: "quantity", type: { kind: "primitive-type", name: "number" } },
|
|
19
|
+
},
|
|
20
|
+
});
|
|
21
|
+
const formatted = formatKaladaV1Expression("price*quantity");
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### Experimental guest-owned expression prefix
|
|
25
|
+
|
|
26
|
+
`experimentalParseKaladaV1GuestExpressionPrefix(source, start, options?)` is an opt-in
|
|
27
|
+
**provisional** public entry for a host that has *already declared* a Kalada expression slot.
|
|
28
|
+
`start` is the UTF-16 offset immediately after the host opener in the **original document**;
|
|
29
|
+
no host grammar is detected or registered by syntax. For example:
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
import { experimentalParseKaladaV1GuestExpressionPrefix, lowerKaladaV1Expression } from "@kalada/syntax";
|
|
33
|
+
|
|
34
|
+
const source = 'text ${price + 1} after';
|
|
35
|
+
const guest = experimentalParseKaladaV1GuestExpressionPrefix(source, source.indexOf("${") + 2);
|
|
36
|
+
if (guest.ok && source[guest.stop] === "}" && guest.parsed) {
|
|
37
|
+
const lowered = lowerKaladaV1Expression(guest.parsed);
|
|
38
|
+
// The host owns and consumes the closing brace; lowering does not evaluate values.
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
The immutable `ExperimentalKaladaV1GuestPrefixResult` reports `ok`, `range` (half-open
|
|
43
|
+
`[start, stop)`), `stop`, `reason`, `diagnostics` and `parsed` (a parse result against the
|
|
44
|
+
original document with absolute UTF-16 token/CST/diagnostic and lowering source-map ranges).
|
|
45
|
+
The guest stops *before* the first outer `}` outside a supported double-quoted string;
|
|
46
|
+
whitespace before it belongs to the guest. `ok` only means a complete, currently supported
|
|
47
|
+
Kalada expression ended at that boundary without syntax diagnostics. The host **must** check
|
|
48
|
+
`source[stop] === "}"` and its own slot rules before consuming anything or authorizing
|
|
49
|
+
lowering/emission; `parsed` on failure is recovery data, **not** permission to emit.
|
|
50
|
+
Reasons are `outer-brace`, `unmatched-parentheses`, `unsupported-comment`,
|
|
51
|
+
`unsupported-quote`, `eof`, `limit`, or `invalid-start`. Unsupported comments, single quotes,
|
|
52
|
+
backticks and brace forms fail closed today; this is not a promise to exclude them from future
|
|
53
|
+
Kalada grammar. An unterminated supported double string may obscure a host brace; bounded
|
|
54
|
+
scanning fails closed rather than guessing ownership. `options.limits` uses the same validated
|
|
55
|
+
syntax limits as whole-expression parsing (including source-window, token and diagnostic
|
|
56
|
+
budgets); no evaluator is invoked. The API name and shape may change before stabilization.
|
|
57
|
+
This is not a Formbar/FSX parser, automatic host integration, or a replacement for
|
|
58
|
+
`parseKaladaV1Expression`.
|
|
59
|
+
|
|
60
|
+
Successful lowering returns the canonical `program`, its `sourceMap`, and syntax's authoritative
|
|
61
|
+
`resultType`. The result projection is `"dynamic"` or a core `KaladaType`; internal uncertainty such
|
|
62
|
+
as an option with an unknown payload is projected as `"dynamic"`.
|
|
63
|
+
|
|
64
|
+
`queryKaladaV1Semantics(parsed, options?)` reports immutable subtree types, field-access support, and
|
|
65
|
+
operator support from the same lowering dispatch internals. It retains useful complete-child facts in
|
|
66
|
+
recovered incomplete source without adding grammar or evaluating values.
|
|
67
|
+
|
|
68
|
+
The frozen initial grammar includes literals, ASCII references, grouping, field navigation,
|
|
69
|
+
arithmetic, comparisons, membership, strict boolean operators, Option coalescing, and ternary
|
|
70
|
+
conditionals. Calls, arrays/objects, constructors, match, functions, imports, and modules are
|
|
71
|
+
intentionally not source forms in this release.
|
|
72
|
+
|
|
73
|
+
Ranges are half-open UTF-16 offsets. Supplying `references` closes the source environment; omitted
|
|
74
|
+
names then fail lowering. Structured references require a matching `coreOptions.reference` codec.
|
|
75
|
+
# Direct WRITE-context locations
|
|
76
|
+
|
|
77
|
+
`checkKaladaV1DirectLocation(source, { bindings })` reparses the **entire** expression and checks a bare bound identifier or a non-optional static dotted chain. For example:
|
|
78
|
+
|
|
79
|
+
```ts
|
|
80
|
+
import { checkKaladaV1DirectLocation } from "@kalada/syntax";
|
|
81
|
+
|
|
82
|
+
const result = checkKaladaV1DirectLocation("(line.quantity)", {
|
|
83
|
+
bindings: {
|
|
84
|
+
line: {
|
|
85
|
+
target: { namespace: "data", scope: "line", segments: [] },
|
|
86
|
+
type: { kind: "primitive-type", name: "json" },
|
|
87
|
+
writable: true,
|
|
88
|
+
properties: {
|
|
89
|
+
quantity: { type: { kind: "primitive-type", name: "number" }, writable: true },
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
});
|
|
94
|
+
// On success: { target: { namespace: "data", scope: "line", segments: ["quantity"] },
|
|
95
|
+
// type: { kind: "primitive-type", name: "number" }, range: { start: 0, end: 15 } }
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Bindings and each traversed property's type and writability must be supplied by a trusted host. A read-context reference, `queryKaladaV1Semantics` field type (`dynamic`), spelling, a caller-provided CST, or a lowered value program is **not** WRITE authority. The checker rejects missing or unsafe metadata, optional/dynamic/computed/index/conditional expressions and recovered parse input. The frozen result is static evidence, **not** a serialized write capability or runtime authorization. Formbar #195/#185 must reauthorize namespace, scope, path, type and writability against current host state **at use time**; Kalada does not perform mutation or evaluator writes.
|