@ldclabs/kip-lang 2.1.0 → 2.2.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 +52 -0
- package/README.md +4 -4
- package/dist/ast.d.ts +58 -57
- package/dist/ast.d.ts.map +1 -1
- package/dist/exec-ast.d.ts +35 -51
- package/dist/exec-ast.d.ts.map +1 -1
- package/dist/formatter.d.ts.map +1 -1
- package/dist/formatter.js +41 -122
- 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 +91 -96
- package/dist/lower.js.map +1 -1
- package/dist/parser.d.ts.map +1 -1
- package/dist/parser.js +98 -223
- 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 -11
- package/dist/token.d.ts.map +1 -1
- package/dist/token.js +2 -22
- 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 -71
- package/src/exec-ast.ts +38 -45
- package/src/formatter.ts +42 -140
- package/src/index.ts +5 -13
- package/src/lower.ts +108 -105
- package/src/parser.ts +103 -251
- package/src/semantics.ts +60 -35
- package/src/token.ts +2 -22
- 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',
|
|
@@ -216,8 +206,8 @@ export const KEYWORDS: ReadonlyMap<string, TokenType> = new Map([
|
|
|
216
206
|
['DISTINCT', TokenType.Distinct],
|
|
217
207
|
['AS', TokenType.As],
|
|
218
208
|
['OF', TokenType.Of],
|
|
209
|
+
['AT', TokenType.At],
|
|
219
210
|
['SEQ', TokenType.Seq],
|
|
220
|
-
['TX', TokenType.Tx],
|
|
221
211
|
['TIME', TokenType.Time],
|
|
222
212
|
['FOR', TokenType.For],
|
|
223
213
|
['EPISTEMIC', TokenType.Epistemic],
|
|
@@ -238,15 +228,10 @@ export const KEYWORDS: ReadonlyMap<string, TokenType> = new Map([
|
|
|
238
228
|
['ASSERT', TokenType.Assert],
|
|
239
229
|
['SUPERSEDING', TokenType.Superseding],
|
|
240
230
|
['UPDATE', TokenType.Update],
|
|
241
|
-
['RETRACT', TokenType.Retract],
|
|
242
|
-
['SUPERSEDE', TokenType.Supersede],
|
|
243
|
-
['CORRECT', TokenType.Correct],
|
|
244
231
|
['TRANSITION', TokenType.Transition],
|
|
245
232
|
['SET', TokenType.Set],
|
|
246
233
|
['UNSET', TokenType.Unset],
|
|
247
234
|
['RETENTION', TokenType.Retention],
|
|
248
|
-
['ARCHIVE', TokenType.Archive],
|
|
249
|
-
['TOMBSTONE', TokenType.Tombstone],
|
|
250
235
|
['PURGE', TokenType.Purge],
|
|
251
236
|
['PAYLOAD', TokenType.Payload],
|
|
252
237
|
['CONFIRM', TokenType.Confirm],
|
|
@@ -265,7 +250,6 @@ export const KEYWORDS: ReadonlyMap<string, TokenType> = new Map([
|
|
|
265
250
|
['FACET', TokenType.Facet],
|
|
266
251
|
['EXPECT', TokenType.Expect],
|
|
267
252
|
['VERSION', TokenType.Version],
|
|
268
|
-
['STATE', TokenType.State],
|
|
269
253
|
|
|
270
254
|
// META
|
|
271
255
|
['DESCRIBE', TokenType.Describe],
|
|
@@ -281,10 +265,7 @@ export const KEYWORDS: ReadonlyMap<string, TokenType> = new Map([
|
|
|
281
265
|
['PRIMER', TokenType.Primer],
|
|
282
266
|
['MODE', TokenType.Mode],
|
|
283
267
|
['PROTOCOL', TokenType.Protocol],
|
|
284
|
-
['EXECUTION', TokenType.Execution],
|
|
285
|
-
['CONTEXT', TokenType.Context],
|
|
286
268
|
['CAPABILITIES', TokenType.Capabilities],
|
|
287
|
-
['CAPABILITY', TokenType.Capability],
|
|
288
269
|
['SPACE', TokenType.Space],
|
|
289
270
|
['SPACES', TokenType.Spaces],
|
|
290
271
|
['SCHEMA', TokenType.Schema],
|
|
@@ -305,7 +286,6 @@ export const KEYWORDS: ReadonlyMap<string, TokenType> = new Map([
|
|
|
305
286
|
['TRANSACTION', TokenType.Transaction],
|
|
306
287
|
['IDEMPOTENCY', TokenType.Idempotency],
|
|
307
288
|
['CAPSULE', TokenType.Capsule],
|
|
308
|
-
['PROJECTION', TokenType.Projection],
|
|
309
289
|
['TRUST', TokenType.Trust],
|
|
310
290
|
['ACCESS', TokenType.Access],
|
|
311
291
|
['WITH', TokenType.With],
|
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.2.0'
|
|
11
11
|
|
|
12
12
|
/** The KIP specification revision this grammar targets. */
|
|
13
13
|
export const KIP_SPEC_REVISION = '2.0-draft'
|