@ldclabs/kip-lang 2.1.0 → 2.3.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/CHANGELOG.md +64 -0
- package/README.md +4 -4
- package/dist/ast.d.ts +59 -58
- package/dist/ast.d.ts.map +1 -1
- package/dist/exec-ast.d.ts +36 -52
- package/dist/exec-ast.d.ts.map +1 -1
- package/dist/formatter.d.ts.map +1 -1
- package/dist/formatter.js +42 -125
- package/dist/formatter.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/lower.d.ts.map +1 -1
- package/dist/lower.js +92 -99
- package/dist/lower.js.map +1 -1
- package/dist/parser.d.ts.map +1 -1
- package/dist/parser.js +98 -231
- package/dist/parser.js.map +1 -1
- package/dist/semantics.js +63 -33
- package/dist/semantics.js.map +1 -1
- package/dist/token.d.ts +1 -13
- package/dist/token.d.ts.map +1 -1
- package/dist/token.js +2 -26
- package/dist/token.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +2 -2
- package/src/ast.ts +55 -73
- package/src/exec-ast.ts +38 -47
- package/src/formatter.ts +43 -143
- package/src/index.ts +5 -13
- package/src/lower.ts +109 -108
- package/src/parser.ts +103 -259
- package/src/semantics.ts +60 -35
- package/src/token.ts +2 -26
- package/src/version.ts +1 -1
package/src/semantics.ts
CHANGED
|
@@ -48,13 +48,27 @@ const MODES = new Set([
|
|
|
48
48
|
'imported'
|
|
49
49
|
])
|
|
50
50
|
const SEARCH_MODES = new Set(['keyword', 'semantic', 'hybrid'])
|
|
51
|
-
|
|
52
|
-
|
|
51
|
+
/**
|
|
52
|
+
* Everything `TRANSITION ... TO` may name (Spec §52.5): Assertion revision,
|
|
53
|
+
* Evidence correction, Activity status, and the storage lifecycle any element
|
|
54
|
+
* has. The engine matches the state to the target's kind; the toolkit can only
|
|
55
|
+
* reject a word that belongs to none of them.
|
|
56
|
+
*/
|
|
57
|
+
const TRANSITION_STATES = new Set([
|
|
53
58
|
'retracted',
|
|
54
59
|
'superseded',
|
|
55
|
-
'
|
|
60
|
+
'corrected',
|
|
61
|
+
'running',
|
|
62
|
+
'completed',
|
|
63
|
+
'failed',
|
|
64
|
+
'cancelled',
|
|
65
|
+
'archived',
|
|
66
|
+
'tombstoned'
|
|
56
67
|
])
|
|
57
|
-
|
|
68
|
+
/** Moves that name the replacing element with `BY`. */
|
|
69
|
+
const TRANSITION_WITH_BY = new Set(['superseded', 'corrected'])
|
|
70
|
+
/** Moves that may finalize an Activity's fields and topology. */
|
|
71
|
+
const ACTIVITY_STATES = new Set(['running', 'completed', 'failed', 'cancelled'])
|
|
58
72
|
const EVIDENCE_ROLES = new Set(['support', 'challenge', 'context'])
|
|
59
73
|
|
|
60
74
|
/** Signals the Profile fixes to `[0,1]`; none of them is truth. */
|
|
@@ -127,36 +141,44 @@ function analyzeMutationClause(stmt: Statement, diags: Diagnostic[]): void {
|
|
|
127
141
|
if (stmt.where) checkWhere(stmt.where, !!stmt.limit, diags)
|
|
128
142
|
break
|
|
129
143
|
|
|
130
|
-
//
|
|
131
|
-
//
|
|
132
|
-
//
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
144
|
+
// The target's kind is not known statically, so only the vocabulary is
|
|
145
|
+
// checkable: a state no kind has, a `BY` on a move that takes none, a
|
|
146
|
+
// finalize clause on a move that is not an Activity's.
|
|
147
|
+
case 'TransitionStatement': {
|
|
148
|
+
checkEnum(stmt.to, TRANSITION_STATES, 'TRANSITION TO', diags)
|
|
149
|
+
if (stmt.to.kind === 'StringLiteral') {
|
|
150
|
+
const to = stmt.to.parsed
|
|
151
|
+
if (TRANSITION_WITH_BY.has(to) && !stmt.by) {
|
|
152
|
+
diags.push({
|
|
153
|
+
range: stmt.to.range,
|
|
154
|
+
severity: 'error',
|
|
155
|
+
message: `TRANSITION TO "${to}" names the replacing element with BY`,
|
|
156
|
+
code: 'KIP_2001'
|
|
157
|
+
})
|
|
158
|
+
}
|
|
159
|
+
if (!TRANSITION_WITH_BY.has(to) && stmt.by && TRANSITION_STATES.has(to)) {
|
|
160
|
+
diags.push({
|
|
161
|
+
range: stmt.by.range,
|
|
162
|
+
severity: 'error',
|
|
163
|
+
message: `TRANSITION TO "${to}" takes no BY`,
|
|
164
|
+
code: 'KIP_2001'
|
|
165
|
+
})
|
|
166
|
+
}
|
|
167
|
+
if (stmt.finalize.length > 0 && !ACTIVITY_STATES.has(to) && TRANSITION_STATES.has(to)) {
|
|
168
|
+
diags.push({
|
|
169
|
+
range: stmt.finalize[0].range,
|
|
170
|
+
severity: 'error',
|
|
171
|
+
message: `TRANSITION TO "${to}" cannot finalize fields or topology; only a pending Activity does`,
|
|
172
|
+
code: 'KIP_2001'
|
|
173
|
+
})
|
|
174
|
+
}
|
|
146
175
|
}
|
|
147
|
-
break
|
|
148
|
-
|
|
149
|
-
case 'ArchiveStatement':
|
|
150
|
-
case 'TombstoneStatement':
|
|
151
|
-
if (stmt.where) checkWhere(stmt.where, !!stmt.limit, diags)
|
|
152
|
-
break
|
|
153
|
-
|
|
154
|
-
case 'TransitionActivityStatement':
|
|
155
|
-
checkEnum(stmt.to, ACTIVITY_TERMINAL, 'TRANSITION ACTIVITY TO', diags)
|
|
156
176
|
checkStructural(stmt.finalize.find(
|
|
157
177
|
(c): c is SetStructuralClause => c.kind === 'SetStructuralClause'
|
|
158
178
|
), diags)
|
|
179
|
+
if (stmt.where) checkWhere(stmt.where, !!stmt.limit, diags)
|
|
159
180
|
break
|
|
181
|
+
}
|
|
160
182
|
|
|
161
183
|
// Spec §52.7 names seven statements whose WHERE can select an unbounded
|
|
162
184
|
// set and which SHOULD therefore carry a LIMIT. Warning on the read and on
|
|
@@ -377,12 +399,15 @@ function collectHandleRefs(
|
|
|
377
399
|
}
|
|
378
400
|
break
|
|
379
401
|
|
|
380
|
-
case '
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
402
|
+
case 'TransitionStatement':
|
|
403
|
+
// `BY ?new` resolves inside the plan; a `?target` is bound by WHERE or
|
|
404
|
+
// by a handle, so only the replacing element is a plan reference.
|
|
405
|
+
if (clause.by && clause.by.kind === 'VariableRef') {
|
|
406
|
+
out.push({ name: clause.by.name.slice(1), range: clause.by.range })
|
|
407
|
+
}
|
|
408
|
+
for (const fin of clause.finalize) {
|
|
409
|
+
if (fin.kind === 'SetFieldsClause') fromObject(fin.assignments)
|
|
410
|
+
else for (const edge of fin.assignments) fromExpression(edge.value)
|
|
386
411
|
}
|
|
387
412
|
break
|
|
388
413
|
}
|
package/src/token.ts
CHANGED
|
@@ -33,8 +33,8 @@ export enum TokenType {
|
|
|
33
33
|
Distinct = 'DISTINCT',
|
|
34
34
|
As = 'AS',
|
|
35
35
|
Of = 'OF',
|
|
36
|
+
At = 'AT',
|
|
36
37
|
Seq = 'SEQ',
|
|
37
|
-
Tx = 'TX',
|
|
38
38
|
Time = 'TIME',
|
|
39
39
|
For = 'FOR',
|
|
40
40
|
Epistemic = 'EPISTEMIC',
|
|
@@ -55,15 +55,10 @@ export enum TokenType {
|
|
|
55
55
|
Assert = 'ASSERT',
|
|
56
56
|
Superseding = 'SUPERSEDING',
|
|
57
57
|
Update = 'UPDATE',
|
|
58
|
-
Retract = 'RETRACT',
|
|
59
|
-
Supersede = 'SUPERSEDE',
|
|
60
|
-
Correct = 'CORRECT',
|
|
61
58
|
Transition = 'TRANSITION',
|
|
62
59
|
Set = 'SET',
|
|
63
60
|
Unset = 'UNSET',
|
|
64
61
|
Retention = 'RETENTION',
|
|
65
|
-
Archive = 'ARCHIVE',
|
|
66
|
-
Tombstone = 'TOMBSTONE',
|
|
67
62
|
Purge = 'PURGE',
|
|
68
63
|
Payload = 'PAYLOAD',
|
|
69
64
|
Confirm = 'CONFIRM',
|
|
@@ -82,7 +77,6 @@ export enum TokenType {
|
|
|
82
77
|
Facet = 'FACET',
|
|
83
78
|
Expect = 'EXPECT',
|
|
84
79
|
Version = 'VERSION',
|
|
85
|
-
State = 'STATE',
|
|
86
80
|
|
|
87
81
|
// ── Keywords — META ───────────────────────────────────────────────
|
|
88
82
|
Describe = 'DESCRIBE',
|
|
@@ -98,10 +92,7 @@ export enum TokenType {
|
|
|
98
92
|
Primer = 'PRIMER',
|
|
99
93
|
Mode = 'MODE',
|
|
100
94
|
Protocol = 'PROTOCOL',
|
|
101
|
-
Execution = 'EXECUTION',
|
|
102
|
-
Context = 'CONTEXT',
|
|
103
95
|
Capabilities = 'CAPABILITIES',
|
|
104
|
-
Capability = 'CAPABILITY',
|
|
105
96
|
Space = 'SPACE',
|
|
106
97
|
Spaces = 'SPACES',
|
|
107
98
|
Schema = 'SCHEMA',
|
|
@@ -122,7 +113,6 @@ export enum TokenType {
|
|
|
122
113
|
Transaction = 'TRANSACTION',
|
|
123
114
|
Idempotency = 'IDEMPOTENCY',
|
|
124
115
|
Capsule = 'CAPSULE',
|
|
125
|
-
Projection = 'PROJECTION',
|
|
126
116
|
Trust = 'TRUST',
|
|
127
117
|
Access = 'ACCESS',
|
|
128
118
|
With = 'WITH',
|
|
@@ -130,8 +120,6 @@ export enum TokenType {
|
|
|
130
120
|
Cognition = 'COGNITION',
|
|
131
121
|
Threshold = 'THRESHOLD',
|
|
132
122
|
Receipt = 'RECEIPT',
|
|
133
|
-
Blob = 'BLOB',
|
|
134
|
-
Checkpoint = 'CHECKPOINT',
|
|
135
123
|
Kql = 'KQL',
|
|
136
124
|
Kml = 'KML',
|
|
137
125
|
Import = 'IMPORT',
|
|
@@ -216,8 +204,8 @@ export const KEYWORDS: ReadonlyMap<string, TokenType> = new Map([
|
|
|
216
204
|
['DISTINCT', TokenType.Distinct],
|
|
217
205
|
['AS', TokenType.As],
|
|
218
206
|
['OF', TokenType.Of],
|
|
207
|
+
['AT', TokenType.At],
|
|
219
208
|
['SEQ', TokenType.Seq],
|
|
220
|
-
['TX', TokenType.Tx],
|
|
221
209
|
['TIME', TokenType.Time],
|
|
222
210
|
['FOR', TokenType.For],
|
|
223
211
|
['EPISTEMIC', TokenType.Epistemic],
|
|
@@ -238,15 +226,10 @@ export const KEYWORDS: ReadonlyMap<string, TokenType> = new Map([
|
|
|
238
226
|
['ASSERT', TokenType.Assert],
|
|
239
227
|
['SUPERSEDING', TokenType.Superseding],
|
|
240
228
|
['UPDATE', TokenType.Update],
|
|
241
|
-
['RETRACT', TokenType.Retract],
|
|
242
|
-
['SUPERSEDE', TokenType.Supersede],
|
|
243
|
-
['CORRECT', TokenType.Correct],
|
|
244
229
|
['TRANSITION', TokenType.Transition],
|
|
245
230
|
['SET', TokenType.Set],
|
|
246
231
|
['UNSET', TokenType.Unset],
|
|
247
232
|
['RETENTION', TokenType.Retention],
|
|
248
|
-
['ARCHIVE', TokenType.Archive],
|
|
249
|
-
['TOMBSTONE', TokenType.Tombstone],
|
|
250
233
|
['PURGE', TokenType.Purge],
|
|
251
234
|
['PAYLOAD', TokenType.Payload],
|
|
252
235
|
['CONFIRM', TokenType.Confirm],
|
|
@@ -265,7 +248,6 @@ export const KEYWORDS: ReadonlyMap<string, TokenType> = new Map([
|
|
|
265
248
|
['FACET', TokenType.Facet],
|
|
266
249
|
['EXPECT', TokenType.Expect],
|
|
267
250
|
['VERSION', TokenType.Version],
|
|
268
|
-
['STATE', TokenType.State],
|
|
269
251
|
|
|
270
252
|
// META
|
|
271
253
|
['DESCRIBE', TokenType.Describe],
|
|
@@ -281,10 +263,7 @@ export const KEYWORDS: ReadonlyMap<string, TokenType> = new Map([
|
|
|
281
263
|
['PRIMER', TokenType.Primer],
|
|
282
264
|
['MODE', TokenType.Mode],
|
|
283
265
|
['PROTOCOL', TokenType.Protocol],
|
|
284
|
-
['EXECUTION', TokenType.Execution],
|
|
285
|
-
['CONTEXT', TokenType.Context],
|
|
286
266
|
['CAPABILITIES', TokenType.Capabilities],
|
|
287
|
-
['CAPABILITY', TokenType.Capability],
|
|
288
267
|
['SPACE', TokenType.Space],
|
|
289
268
|
['SPACES', TokenType.Spaces],
|
|
290
269
|
['SCHEMA', TokenType.Schema],
|
|
@@ -305,7 +284,6 @@ export const KEYWORDS: ReadonlyMap<string, TokenType> = new Map([
|
|
|
305
284
|
['TRANSACTION', TokenType.Transaction],
|
|
306
285
|
['IDEMPOTENCY', TokenType.Idempotency],
|
|
307
286
|
['CAPSULE', TokenType.Capsule],
|
|
308
|
-
['PROJECTION', TokenType.Projection],
|
|
309
287
|
['TRUST', TokenType.Trust],
|
|
310
288
|
['ACCESS', TokenType.Access],
|
|
311
289
|
['WITH', TokenType.With],
|
|
@@ -313,8 +291,6 @@ export const KEYWORDS: ReadonlyMap<string, TokenType> = new Map([
|
|
|
313
291
|
['COGNITION', TokenType.Cognition],
|
|
314
292
|
['THRESHOLD', TokenType.Threshold],
|
|
315
293
|
['RECEIPT', TokenType.Receipt],
|
|
316
|
-
['BLOB', TokenType.Blob],
|
|
317
|
-
['CHECKPOINT', TokenType.Checkpoint],
|
|
318
294
|
['KQL', TokenType.Kql],
|
|
319
295
|
['KML', TokenType.Kml],
|
|
320
296
|
['IMPORT', TokenType.Import],
|
package/src/version.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* has to load in runtimes with no filesystem; `test/lower.test.mjs` asserts the
|
|
8
8
|
* two stay in step.
|
|
9
9
|
*/
|
|
10
|
-
export const PARSER_VERSION = '2.
|
|
10
|
+
export const PARSER_VERSION = '2.3.0'
|
|
11
11
|
|
|
12
12
|
/** The KIP specification revision this grammar targets. */
|
|
13
13
|
export const KIP_SPEC_REVISION = '2.0-draft'
|