@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/dist/parser.js
CHANGED
|
@@ -63,13 +63,8 @@ class Parser {
|
|
|
63
63
|
case TokenType.Ensure:
|
|
64
64
|
case TokenType.Assert:
|
|
65
65
|
case TokenType.Update:
|
|
66
|
-
case TokenType.Retract:
|
|
67
|
-
case TokenType.Supersede:
|
|
68
|
-
case TokenType.Correct:
|
|
69
66
|
case TokenType.Transition:
|
|
70
67
|
case TokenType.Set:
|
|
71
|
-
case TokenType.Archive:
|
|
72
|
-
case TokenType.Tombstone:
|
|
73
68
|
case TokenType.Purge:
|
|
74
69
|
case TokenType.Merge:
|
|
75
70
|
return this.parseMutationClause();
|
|
@@ -90,8 +85,6 @@ class Parser {
|
|
|
90
85
|
return this.parseHistoryStatement();
|
|
91
86
|
case TokenType.Changes:
|
|
92
87
|
return this.parseChangesStatement();
|
|
93
|
-
case TokenType.Snapshot:
|
|
94
|
-
return this.parseSnapshotStatement();
|
|
95
88
|
case TokenType.Export:
|
|
96
89
|
return this.parseExportCapsuleStatement();
|
|
97
90
|
default:
|
|
@@ -113,20 +106,10 @@ class Parser {
|
|
|
113
106
|
return this.parseAssertStatement();
|
|
114
107
|
case TokenType.Update:
|
|
115
108
|
return this.parseUpdateStatement();
|
|
116
|
-
case TokenType.Retract:
|
|
117
|
-
return this.parseRetractAssertion();
|
|
118
|
-
case TokenType.Supersede:
|
|
119
|
-
return this.parseSupersedeAssertion();
|
|
120
|
-
case TokenType.Correct:
|
|
121
|
-
return this.parseCorrectEvidence();
|
|
122
109
|
case TokenType.Transition:
|
|
123
|
-
return this.
|
|
110
|
+
return this.parseTransitionStatement();
|
|
124
111
|
case TokenType.Set:
|
|
125
112
|
return this.parseSetRetention();
|
|
126
|
-
case TokenType.Archive:
|
|
127
|
-
return this.parseArchiveStatement();
|
|
128
|
-
case TokenType.Tombstone:
|
|
129
|
-
return this.parseTombstoneStatement();
|
|
130
113
|
case TokenType.Purge:
|
|
131
114
|
return this.parsePurgeStatement();
|
|
132
115
|
case TokenType.Merge:
|
|
@@ -225,24 +208,15 @@ class Parser {
|
|
|
225
208
|
const start = this.currentPos();
|
|
226
209
|
const first = this.expect(TokenType.As);
|
|
227
210
|
this.expectSecondWord(TokenType.Of, first);
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
basis = 'TX';
|
|
234
|
-
}
|
|
235
|
-
else if (this.match(TokenType.Time)) {
|
|
236
|
-
basis = 'TIME';
|
|
237
|
-
}
|
|
238
|
-
else {
|
|
239
|
-
this.error(`Expected SEQ, TX or TIME after AS OF but got '${this.current().value}'`, this.current());
|
|
240
|
-
basis = 'SEQ';
|
|
211
|
+
// Cognitive time is a sequence coordinate. A transaction id or an instant
|
|
212
|
+
// is resolved to one first (DESCRIBE TRANSACTION / DESCRIBE SNAPSHOT AT
|
|
213
|
+
// TIME), so the read names the sequence it actually ran against.
|
|
214
|
+
if (!this.match(TokenType.Seq)) {
|
|
215
|
+
this.error(`Expected SEQ after AS OF but got '${this.current().value}'`, this.current());
|
|
241
216
|
}
|
|
242
217
|
const value = this.parseScalarValue();
|
|
243
218
|
return {
|
|
244
219
|
kind: 'AsOfClause',
|
|
245
|
-
basis,
|
|
246
220
|
value,
|
|
247
221
|
range: { start, end: this.endPos() }
|
|
248
222
|
};
|
|
@@ -992,6 +966,7 @@ class Parser {
|
|
|
992
966
|
handle,
|
|
993
967
|
setFacets: [],
|
|
994
968
|
unsetFacets: [],
|
|
969
|
+
expectVersions: [],
|
|
995
970
|
range: { start, end: start },
|
|
996
971
|
leadingComments: leadingComments.length ? leadingComments : undefined
|
|
997
972
|
};
|
|
@@ -1006,10 +981,6 @@ class Parser {
|
|
|
1006
981
|
this.rejectRepeat(stmt.match, 'MATCH', tok);
|
|
1007
982
|
stmt.match = this.parseMatchClause();
|
|
1008
983
|
break;
|
|
1009
|
-
case TokenType.Expect:
|
|
1010
|
-
this.rejectRepeat(stmt.expectVersion, 'EXPECT VERSION', tok);
|
|
1011
|
-
stmt.expectVersion = this.parseExpectVersionClause();
|
|
1012
|
-
break;
|
|
1013
984
|
case TokenType.Set: {
|
|
1014
985
|
const clause = this.parseSetClause();
|
|
1015
986
|
if (clause.kind === 'SetFieldsClause') {
|
|
@@ -1055,6 +1026,9 @@ class Parser {
|
|
|
1055
1026
|
break;
|
|
1056
1027
|
}
|
|
1057
1028
|
this.expect(TokenType.RBrace);
|
|
1029
|
+
// Preconditions trail the body, in the one tail order every mutation
|
|
1030
|
+
// shares: [WHERE] [LIMIT] {EXPECT VERSION} (Spec §52.8).
|
|
1031
|
+
stmt.expectVersions = this.parseExpectVersions();
|
|
1058
1032
|
stmt.range = { start, end: this.endPos() };
|
|
1059
1033
|
return stmt;
|
|
1060
1034
|
}
|
|
@@ -1068,14 +1042,12 @@ class Parser {
|
|
|
1068
1042
|
: undefined;
|
|
1069
1043
|
this.dialect = 'raw';
|
|
1070
1044
|
const tuple = this.parsePropositionTuple();
|
|
1071
|
-
const
|
|
1072
|
-
? this.parseExpectVersionClause()
|
|
1073
|
-
: undefined;
|
|
1045
|
+
const expectVersions = this.parseExpectVersions();
|
|
1074
1046
|
return {
|
|
1075
1047
|
kind: 'EnsurePropositionStatement',
|
|
1076
1048
|
handle,
|
|
1077
1049
|
tuple,
|
|
1078
|
-
|
|
1050
|
+
expectVersions,
|
|
1079
1051
|
range: { start, end: this.endPos() },
|
|
1080
1052
|
leadingComments: leadingComments.length ? leadingComments : undefined
|
|
1081
1053
|
};
|
|
@@ -1314,22 +1286,47 @@ class Parser {
|
|
|
1314
1286
|
const expect = this.expect(TokenType.Expect);
|
|
1315
1287
|
this.expectSecondWord(TokenType.Version, expect);
|
|
1316
1288
|
const value = this.parseScalarValue();
|
|
1289
|
+
// `OF <plane>` guards one plane's own version instead of the element's
|
|
1290
|
+
// (Spec §35.1): a verdict guarded on ATTRIBUTES is not spoiled by a
|
|
1291
|
+
// metabolism sweep that touched a Facet.
|
|
1292
|
+
let plane;
|
|
1293
|
+
if (this.match(TokenType.Of)) {
|
|
1294
|
+
const tok = this.current();
|
|
1295
|
+
switch (tok.type) {
|
|
1296
|
+
case TokenType.Attributes:
|
|
1297
|
+
this.advance();
|
|
1298
|
+
plane = { kind: 'ATTRIBUTES' };
|
|
1299
|
+
break;
|
|
1300
|
+
case TokenType.Structural:
|
|
1301
|
+
this.advance();
|
|
1302
|
+
plane = { kind: 'STRUCTURAL' };
|
|
1303
|
+
break;
|
|
1304
|
+
case TokenType.Retention:
|
|
1305
|
+
this.advance();
|
|
1306
|
+
plane = { kind: 'RETENTION' };
|
|
1307
|
+
break;
|
|
1308
|
+
case TokenType.Facet:
|
|
1309
|
+
this.advance();
|
|
1310
|
+
plane = { kind: 'FACET', facet: this.parseSchemaSymbol() };
|
|
1311
|
+
break;
|
|
1312
|
+
default:
|
|
1313
|
+
this.error(`Expected ATTRIBUTES, STRUCTURAL, RETENTION or FACET after OF but got '${tok.value}'`, tok);
|
|
1314
|
+
}
|
|
1315
|
+
}
|
|
1317
1316
|
return {
|
|
1318
1317
|
kind: 'ExpectVersionClause',
|
|
1319
1318
|
value,
|
|
1319
|
+
plane,
|
|
1320
1320
|
range: { start, end: this.endPos() }
|
|
1321
1321
|
};
|
|
1322
1322
|
}
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
const
|
|
1326
|
-
this.
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
value,
|
|
1331
|
-
range: { start, end: this.endPos() }
|
|
1332
|
-
};
|
|
1323
|
+
/** `{ expect_version_clause }` — the trailing precondition list. */
|
|
1324
|
+
parseExpectVersions() {
|
|
1325
|
+
const clauses = [];
|
|
1326
|
+
while (this.check(TokenType.Expect)) {
|
|
1327
|
+
clauses.push(this.parseExpectVersionClause());
|
|
1328
|
+
}
|
|
1329
|
+
return clauses;
|
|
1333
1330
|
}
|
|
1334
1331
|
// ────────────────────────────────────────────────────────────────────
|
|
1335
1332
|
// KML — UPDATE
|
|
@@ -1339,9 +1336,6 @@ class Parser {
|
|
|
1339
1336
|
const start = this.currentPos();
|
|
1340
1337
|
this.expectKeywordWithSpace(TokenType.Update);
|
|
1341
1338
|
const target = this.parseTargetRef();
|
|
1342
|
-
const expectVersion = this.check(TokenType.Expect)
|
|
1343
|
-
? this.parseExpectVersionClause()
|
|
1344
|
-
: undefined;
|
|
1345
1339
|
const actions = [];
|
|
1346
1340
|
for (;;) {
|
|
1347
1341
|
if (this.check(TokenType.Set)) {
|
|
@@ -1363,9 +1357,9 @@ class Parser {
|
|
|
1363
1357
|
this.error('UPDATE requires at least one SET or UNSET action', this.current());
|
|
1364
1358
|
}
|
|
1365
1359
|
// WHERE binds a ?variable target; a direct :id / "id" target already names
|
|
1366
|
-
// the element and may omit it, exactly as
|
|
1367
|
-
// SET RETENTION
|
|
1368
|
-
//
|
|
1360
|
+
// the element and may omit it, exactly as TRANSITION / PURGE /
|
|
1361
|
+
// SET RETENTION do (Spec §58). Whether a bare ?variable is bound is
|
|
1362
|
+
// semantic — inside MUTATE it may be a local handle.
|
|
1369
1363
|
let where;
|
|
1370
1364
|
if (this.check(TokenType.Where)) {
|
|
1371
1365
|
this.expectKeywordWithSpace(TokenType.Where);
|
|
@@ -1373,96 +1367,35 @@ class Parser {
|
|
|
1373
1367
|
where = this.parseWhereClause();
|
|
1374
1368
|
}
|
|
1375
1369
|
const limit = this.check(TokenType.Limit) ? this.parseLimitClause() : undefined;
|
|
1370
|
+
const expectVersions = this.parseExpectVersions();
|
|
1376
1371
|
return {
|
|
1377
1372
|
kind: 'UpdateStatement',
|
|
1378
1373
|
target,
|
|
1379
|
-
expectVersion,
|
|
1380
1374
|
actions,
|
|
1381
1375
|
where,
|
|
1382
1376
|
limit,
|
|
1377
|
+
expectVersions,
|
|
1383
1378
|
range: { start, end: this.endPos() },
|
|
1384
1379
|
leadingComments: leadingComments.length ? leadingComments : undefined
|
|
1385
1380
|
};
|
|
1386
1381
|
}
|
|
1387
1382
|
// ────────────────────────────────────────────────────────────────────
|
|
1388
|
-
// KML — lifecycle
|
|
1383
|
+
// KML — TRANSITION (the one lifecycle statement, Spec §52.5)
|
|
1389
1384
|
// ────────────────────────────────────────────────────────────────────
|
|
1390
|
-
|
|
1391
|
-
const leadingComments = this.collectLeadingComments();
|
|
1392
|
-
const start = this.currentPos();
|
|
1393
|
-
const retract = this.expectKeywordWithSpace(TokenType.Retract);
|
|
1394
|
-
this.expectSecondWord(TokenType.Assertion, retract);
|
|
1395
|
-
const target = this.parseTargetRef();
|
|
1396
|
-
let where;
|
|
1397
|
-
if (this.check(TokenType.Where)) {
|
|
1398
|
-
this.expectKeywordWithSpace(TokenType.Where);
|
|
1399
|
-
this.dialect = 'raw';
|
|
1400
|
-
where = this.parseWhereClause();
|
|
1401
|
-
}
|
|
1402
|
-
const limit = this.check(TokenType.Limit) ? this.parseLimitClause() : undefined;
|
|
1403
|
-
const expectState = this.check(TokenType.Expect)
|
|
1404
|
-
? this.parseExpectStateClause()
|
|
1405
|
-
: undefined;
|
|
1406
|
-
return {
|
|
1407
|
-
kind: 'RetractAssertionStatement',
|
|
1408
|
-
target,
|
|
1409
|
-
where,
|
|
1410
|
-
limit,
|
|
1411
|
-
expectState,
|
|
1412
|
-
range: { start, end: this.endPos() },
|
|
1413
|
-
leadingComments: leadingComments.length ? leadingComments : undefined
|
|
1414
|
-
};
|
|
1415
|
-
}
|
|
1416
|
-
parseSupersedeAssertion() {
|
|
1417
|
-
const leadingComments = this.collectLeadingComments();
|
|
1418
|
-
const start = this.currentPos();
|
|
1419
|
-
const supersede = this.expectKeywordWithSpace(TokenType.Supersede);
|
|
1420
|
-
this.expectSecondWord(TokenType.Assertion, supersede);
|
|
1421
|
-
const target = this.parseTargetRef();
|
|
1422
|
-
this.expect(TokenType.By);
|
|
1423
|
-
const by = this.parseTargetRef();
|
|
1424
|
-
const expectState = this.check(TokenType.Expect)
|
|
1425
|
-
? this.parseExpectStateClause()
|
|
1426
|
-
: undefined;
|
|
1427
|
-
return {
|
|
1428
|
-
kind: 'SupersedeAssertionStatement',
|
|
1429
|
-
target,
|
|
1430
|
-
by,
|
|
1431
|
-
expectState,
|
|
1432
|
-
range: { start, end: this.endPos() },
|
|
1433
|
-
leadingComments: leadingComments.length ? leadingComments : undefined
|
|
1434
|
-
};
|
|
1435
|
-
}
|
|
1436
|
-
parseCorrectEvidence() {
|
|
1437
|
-
const leadingComments = this.collectLeadingComments();
|
|
1438
|
-
const start = this.currentPos();
|
|
1439
|
-
const correct = this.expectKeywordWithSpace(TokenType.Correct);
|
|
1440
|
-
this.expectSecondWord(TokenType.Evidence, correct);
|
|
1441
|
-
const target = this.parseTargetRef();
|
|
1442
|
-
this.expect(TokenType.By);
|
|
1443
|
-
const by = this.parseTargetRef();
|
|
1444
|
-
const expectState = this.check(TokenType.Expect)
|
|
1445
|
-
? this.parseExpectStateClause()
|
|
1446
|
-
: undefined;
|
|
1447
|
-
return {
|
|
1448
|
-
kind: 'CorrectEvidenceStatement',
|
|
1449
|
-
target,
|
|
1450
|
-
by,
|
|
1451
|
-
expectState,
|
|
1452
|
-
range: { start, end: this.endPos() },
|
|
1453
|
-
leadingComments: leadingComments.length ? leadingComments : undefined
|
|
1454
|
-
};
|
|
1455
|
-
}
|
|
1456
|
-
parseTransitionActivity() {
|
|
1385
|
+
parseTransitionStatement() {
|
|
1457
1386
|
const leadingComments = this.collectLeadingComments();
|
|
1458
1387
|
const start = this.currentPos();
|
|
1459
|
-
|
|
1460
|
-
this.expectSecondWord(TokenType.Activity, transition);
|
|
1388
|
+
this.expectKeywordWithSpace(TokenType.Transition);
|
|
1461
1389
|
const target = this.parseTargetRef();
|
|
1462
1390
|
this.expect(TokenType.To);
|
|
1463
1391
|
const to = this.parseScalarValue();
|
|
1464
|
-
//
|
|
1465
|
-
|
|
1392
|
+
// `BY` names the replacing element for "superseded" / "corrected".
|
|
1393
|
+
let by;
|
|
1394
|
+
if (this.match(TokenType.By)) {
|
|
1395
|
+
by = this.parseTargetRef();
|
|
1396
|
+
}
|
|
1397
|
+
// A pending Activity finalizes terminal fields and topology in the same
|
|
1398
|
+
// statement that moves it (Spec §17.5, §52.5).
|
|
1466
1399
|
const finalize = [];
|
|
1467
1400
|
while (this.check(TokenType.Set)) {
|
|
1468
1401
|
const clause = this.parseSetClause();
|
|
@@ -1470,19 +1403,27 @@ class Parser {
|
|
|
1470
1403
|
finalize.push(clause);
|
|
1471
1404
|
}
|
|
1472
1405
|
else {
|
|
1473
|
-
this.error('TRANSITION
|
|
1406
|
+
this.error('TRANSITION accepts only SET FIELDS and SET STRUCTURAL', this.current());
|
|
1474
1407
|
break;
|
|
1475
1408
|
}
|
|
1476
1409
|
}
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1410
|
+
let where;
|
|
1411
|
+
if (this.check(TokenType.Where)) {
|
|
1412
|
+
this.expectKeywordWithSpace(TokenType.Where);
|
|
1413
|
+
this.dialect = 'raw';
|
|
1414
|
+
where = this.parseWhereClause();
|
|
1415
|
+
}
|
|
1416
|
+
const limit = this.check(TokenType.Limit) ? this.parseLimitClause() : undefined;
|
|
1417
|
+
const expectVersions = this.parseExpectVersions();
|
|
1480
1418
|
return {
|
|
1481
|
-
kind: '
|
|
1419
|
+
kind: 'TransitionStatement',
|
|
1482
1420
|
target,
|
|
1483
1421
|
to,
|
|
1422
|
+
by,
|
|
1484
1423
|
finalize,
|
|
1485
|
-
|
|
1424
|
+
where,
|
|
1425
|
+
limit,
|
|
1426
|
+
expectVersions,
|
|
1486
1427
|
range: { start, end: this.endPos() },
|
|
1487
1428
|
leadingComments: leadingComments.length ? leadingComments : undefined
|
|
1488
1429
|
};
|
|
@@ -1504,69 +1445,18 @@ class Parser {
|
|
|
1504
1445
|
where = this.parseWhereClause();
|
|
1505
1446
|
}
|
|
1506
1447
|
const limit = this.check(TokenType.Limit) ? this.parseLimitClause() : undefined;
|
|
1507
|
-
const
|
|
1508
|
-
? this.parseExpectVersionClause()
|
|
1509
|
-
: undefined;
|
|
1448
|
+
const expectVersions = this.parseExpectVersions();
|
|
1510
1449
|
return {
|
|
1511
1450
|
kind: 'SetRetentionStatement',
|
|
1512
1451
|
target,
|
|
1513
1452
|
assignments,
|
|
1514
1453
|
where,
|
|
1515
1454
|
limit,
|
|
1516
|
-
|
|
1455
|
+
expectVersions,
|
|
1517
1456
|
range: { start, end: this.endPos() },
|
|
1518
1457
|
leadingComments: leadingComments.length ? leadingComments : undefined
|
|
1519
1458
|
};
|
|
1520
1459
|
}
|
|
1521
|
-
parseArchiveStatement() {
|
|
1522
|
-
const { start, target, where, limit, expectState, leadingComments } = this.parseRemovalBody(TokenType.Archive);
|
|
1523
|
-
return {
|
|
1524
|
-
kind: 'ArchiveStatement',
|
|
1525
|
-
target,
|
|
1526
|
-
where,
|
|
1527
|
-
limit,
|
|
1528
|
-
expectState,
|
|
1529
|
-
range: { start, end: this.endPos() },
|
|
1530
|
-
leadingComments
|
|
1531
|
-
};
|
|
1532
|
-
}
|
|
1533
|
-
parseTombstoneStatement() {
|
|
1534
|
-
const { start, target, where, limit, expectState, leadingComments } = this.parseRemovalBody(TokenType.Tombstone);
|
|
1535
|
-
return {
|
|
1536
|
-
kind: 'TombstoneStatement',
|
|
1537
|
-
target,
|
|
1538
|
-
where,
|
|
1539
|
-
limit,
|
|
1540
|
-
expectState,
|
|
1541
|
-
range: { start, end: this.endPos() },
|
|
1542
|
-
leadingComments
|
|
1543
|
-
};
|
|
1544
|
-
}
|
|
1545
|
-
/** ARCHIVE and TOMBSTONE share one shape; PURGE adds its confirmation. */
|
|
1546
|
-
parseRemovalBody(keyword) {
|
|
1547
|
-
const comments = this.collectLeadingComments();
|
|
1548
|
-
const start = this.currentPos();
|
|
1549
|
-
this.expectKeywordWithSpace(keyword);
|
|
1550
|
-
const target = this.parseTargetRef();
|
|
1551
|
-
let where;
|
|
1552
|
-
if (this.check(TokenType.Where)) {
|
|
1553
|
-
this.expectKeywordWithSpace(TokenType.Where);
|
|
1554
|
-
this.dialect = 'raw';
|
|
1555
|
-
where = this.parseWhereClause();
|
|
1556
|
-
}
|
|
1557
|
-
const limit = this.check(TokenType.Limit) ? this.parseLimitClause() : undefined;
|
|
1558
|
-
const expectState = this.check(TokenType.Expect)
|
|
1559
|
-
? this.parseExpectStateClause()
|
|
1560
|
-
: undefined;
|
|
1561
|
-
return {
|
|
1562
|
-
start,
|
|
1563
|
-
target,
|
|
1564
|
-
where,
|
|
1565
|
-
limit,
|
|
1566
|
-
expectState,
|
|
1567
|
-
leadingComments: comments.length ? comments : undefined
|
|
1568
|
-
};
|
|
1569
|
-
}
|
|
1570
1460
|
parsePurgeStatement() {
|
|
1571
1461
|
const leadingComments = this.collectLeadingComments();
|
|
1572
1462
|
const start = this.currentPos();
|
|
@@ -1582,6 +1472,7 @@ class Parser {
|
|
|
1582
1472
|
where = this.parseWhereClause();
|
|
1583
1473
|
}
|
|
1584
1474
|
const limit = this.check(TokenType.Limit) ? this.parseLimitClause() : undefined;
|
|
1475
|
+
const expectVersions = this.parseExpectVersions();
|
|
1585
1476
|
let referencePolicy;
|
|
1586
1477
|
if (this.check(TokenType.Reference)) {
|
|
1587
1478
|
const reference = this.expect(TokenType.Reference);
|
|
@@ -1602,6 +1493,7 @@ class Parser {
|
|
|
1602
1493
|
target,
|
|
1603
1494
|
where,
|
|
1604
1495
|
limit,
|
|
1496
|
+
expectVersions,
|
|
1605
1497
|
referencePolicy,
|
|
1606
1498
|
confirm,
|
|
1607
1499
|
range: { start, end: this.endPos() },
|
|
@@ -1623,6 +1515,7 @@ class Parser {
|
|
|
1623
1515
|
where = this.parseWhereClause();
|
|
1624
1516
|
}
|
|
1625
1517
|
const limit = this.check(TokenType.Limit) ? this.parseLimitClause() : undefined;
|
|
1518
|
+
const expectVersions = this.parseExpectVersions();
|
|
1626
1519
|
this.expect(TokenType.Confirm);
|
|
1627
1520
|
const confirmTok = this.current();
|
|
1628
1521
|
const confirm = this.parseStringLiteral();
|
|
@@ -1634,6 +1527,7 @@ class Parser {
|
|
|
1634
1527
|
target,
|
|
1635
1528
|
where,
|
|
1636
1529
|
limit,
|
|
1530
|
+
expectVersions,
|
|
1637
1531
|
confirm,
|
|
1638
1532
|
range: { start, end: this.endPos() },
|
|
1639
1533
|
leadingComments: leadingComments.length ? leadingComments : undefined
|
|
@@ -1653,15 +1547,13 @@ class Parser {
|
|
|
1653
1547
|
this.dialect = 'raw';
|
|
1654
1548
|
where = this.parseWhereClause();
|
|
1655
1549
|
}
|
|
1656
|
-
const
|
|
1657
|
-
? this.parseExpectVersionClause()
|
|
1658
|
-
: undefined;
|
|
1550
|
+
const expectVersions = this.parseExpectVersions();
|
|
1659
1551
|
return {
|
|
1660
1552
|
kind: 'MergeConceptStatement',
|
|
1661
1553
|
source,
|
|
1662
1554
|
into,
|
|
1663
1555
|
where,
|
|
1664
|
-
|
|
1556
|
+
expectVersions,
|
|
1665
1557
|
range: { start, end: this.endPos() },
|
|
1666
1558
|
leadingComments: leadingComments.length ? leadingComments : undefined
|
|
1667
1559
|
};
|
|
@@ -1692,11 +1584,6 @@ class Parser {
|
|
|
1692
1584
|
case TokenType.Protocol:
|
|
1693
1585
|
this.expectSecondWord(TokenType.Protocol, describe);
|
|
1694
1586
|
return stmt('PROTOCOL');
|
|
1695
|
-
case TokenType.Execution: {
|
|
1696
|
-
const exec = this.expectSecondWord(TokenType.Execution, describe);
|
|
1697
|
-
this.expectSecondWord(TokenType.Context, exec);
|
|
1698
|
-
return stmt('EXECUTION_CONTEXT');
|
|
1699
|
-
}
|
|
1700
1587
|
case TokenType.Capabilities:
|
|
1701
1588
|
this.expectSecondWord(TokenType.Capabilities, describe);
|
|
1702
1589
|
return stmt('CAPABILITIES');
|
|
@@ -1753,8 +1640,19 @@ class Parser {
|
|
|
1753
1640
|
}
|
|
1754
1641
|
case TokenType.Snapshot: {
|
|
1755
1642
|
this.expectSecondWord(TokenType.Snapshot, describe);
|
|
1756
|
-
|
|
1757
|
-
|
|
1643
|
+
// A snapshot is addressed by sequence, or resolved from an instant:
|
|
1644
|
+
// the one place wall-clock time enters cognitive-time addressing.
|
|
1645
|
+
let asOf;
|
|
1646
|
+
let atTime;
|
|
1647
|
+
if (this.check(TokenType.As)) {
|
|
1648
|
+
asOf = this.parseAsOfClause();
|
|
1649
|
+
}
|
|
1650
|
+
else if (this.check(TokenType.At)) {
|
|
1651
|
+
const at = this.expect(TokenType.At);
|
|
1652
|
+
this.expectSecondWord(TokenType.Time, at);
|
|
1653
|
+
atTime = this.parseScalarValue();
|
|
1654
|
+
}
|
|
1655
|
+
return stmt('SNAPSHOT', { asOf, atTime });
|
|
1758
1656
|
}
|
|
1759
1657
|
case TokenType.Capsule:
|
|
1760
1658
|
this.expectSecondWord(TokenType.Capsule, describe);
|
|
@@ -1765,11 +1663,6 @@ class Parser {
|
|
|
1765
1663
|
const value = this.isMetaValueStart() ? this.parseScalarValue() : undefined;
|
|
1766
1664
|
return stmt('EPISTEMIC_POLICY', { value });
|
|
1767
1665
|
}
|
|
1768
|
-
case TokenType.Projection: {
|
|
1769
|
-
const projection = this.expectSecondWord(TokenType.Projection, describe);
|
|
1770
|
-
this.expectSecondWord(TokenType.Capability, projection);
|
|
1771
|
-
return stmt('PROJECTION_CAPABILITY');
|
|
1772
|
-
}
|
|
1773
1666
|
case TokenType.Trust: {
|
|
1774
1667
|
this.expectSecondWord(TokenType.Trust, describe);
|
|
1775
1668
|
const value = this.isMetaValueStart() ? this.parseScalarValue() : undefined;
|
|
@@ -2077,7 +1970,7 @@ class Parser {
|
|
|
2077
1970
|
throw new ParseAbort();
|
|
2078
1971
|
}
|
|
2079
1972
|
// ────────────────────────────────────────────────────────────────────
|
|
2080
|
-
// META — HISTORY / CHANGES
|
|
1973
|
+
// META — HISTORY / CHANGES
|
|
2081
1974
|
// ────────────────────────────────────────────────────────────────────
|
|
2082
1975
|
parseHistoryStatement() {
|
|
2083
1976
|
const leadingComments = this.collectLeadingComments();
|
|
@@ -2156,18 +2049,6 @@ class Parser {
|
|
|
2156
2049
|
leadingComments: leadingComments.length ? leadingComments : undefined
|
|
2157
2050
|
};
|
|
2158
2051
|
}
|
|
2159
|
-
parseSnapshotStatement() {
|
|
2160
|
-
const leadingComments = this.collectLeadingComments();
|
|
2161
|
-
const start = this.currentPos();
|
|
2162
|
-
this.expect(TokenType.Snapshot);
|
|
2163
|
-
const asOf = this.check(TokenType.As) ? this.parseAsOfClause() : undefined;
|
|
2164
|
-
return {
|
|
2165
|
-
kind: 'SnapshotStatement',
|
|
2166
|
-
asOf,
|
|
2167
|
-
range: { start, end: this.endPos() },
|
|
2168
|
-
leadingComments: leadingComments.length ? leadingComments : undefined
|
|
2169
|
-
};
|
|
2170
|
-
}
|
|
2171
2052
|
// ────────────────────────────────────────────────────────────────────
|
|
2172
2053
|
// META — EXPORT CAPSULE
|
|
2173
2054
|
// ────────────────────────────────────────────────────────────────────
|
|
@@ -2996,13 +2877,8 @@ class Parser {
|
|
|
2996
2877
|
TokenType.Ensure,
|
|
2997
2878
|
TokenType.Assert,
|
|
2998
2879
|
TokenType.Update,
|
|
2999
|
-
TokenType.Retract,
|
|
3000
|
-
TokenType.Supersede,
|
|
3001
|
-
TokenType.Correct,
|
|
3002
2880
|
TokenType.Transition,
|
|
3003
2881
|
TokenType.Set,
|
|
3004
|
-
TokenType.Archive,
|
|
3005
|
-
TokenType.Tombstone,
|
|
3006
2882
|
TokenType.Purge,
|
|
3007
2883
|
TokenType.Merge,
|
|
3008
2884
|
TokenType.Describe,
|
|
@@ -3013,7 +2889,6 @@ class Parser {
|
|
|
3013
2889
|
TokenType.Preview,
|
|
3014
2890
|
TokenType.History,
|
|
3015
2891
|
TokenType.Changes,
|
|
3016
|
-
TokenType.Snapshot,
|
|
3017
2892
|
TokenType.Export,
|
|
3018
2893
|
TokenType.EOF
|
|
3019
2894
|
]);
|