Skip to content

Commit 6998c50

Browse files
committed
fixup! refactor M.has
1 parent ae71eec commit 6998c50

File tree

5 files changed

+105
-50
lines changed

5 files changed

+105
-50
lines changed

packages/nat/src/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ function isNat(allegedNum) {
5555
*/
5656
function Nat(allegedNum) {
5757
if (typeof allegedNum === 'bigint') {
58-
if (allegedNum < 0) {
58+
if (allegedNum < 0n) {
5959
throw RangeError(`${allegedNum} is negative`);
6060
}
6161
return allegedNum;

packages/patterns/index.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,7 @@ export {
6565
assertMethodGuard,
6666
assertInterfaceGuard,
6767
kindOf,
68-
elementsHasSplit,
69-
pairsHasSplit,
68+
copyStuffHasSplit,
7069
} from './src/patterns/patternMatchers.js';
7170

7271
export {

packages/patterns/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
"@endo/errors": "workspace:^",
3737
"@endo/eventual-send": "workspace:^",
3838
"@endo/marshal": "workspace:^",
39+
"@endo/pass-style": "workspace:^",
3940
"@endo/promise-kit": "workspace:^"
4041
},
4142
"devDependencies": {

packages/patterns/src/keys/merge-bag-operators.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import { q, Fail } from '@endo/errors';
88
import { assertNoDuplicateKeys, makeBagOfEntries } from './copyBag.js';
99

1010
/**
11-
* @import {Passable} from '@endo/pass-style';
1211
* @import {FullCompare, RankCompare} from '@endo/marshal'
1312
* @import {Key} from '../types.js'
1413
*/

packages/patterns/src/patterns/patternMatchers.js

Lines changed: 102 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
/* eslint-disable @endo/no-optional-chaining */
22
// @ts-nocheck So many errors that the suppressions hamper readability.
33
// TODO parameterize MatchHelper which will solve most of them
4+
import { q, b, X, Fail, makeError, annotateError } from '@endo/errors';
5+
import { identChecker } from '@endo/common/ident-checker.js';
6+
import { applyLabelingError } from '@endo/common/apply-labeling-error.js';
7+
import { fromUniqueEntries } from '@endo/common/from-unique-entries.js';
8+
import { listDifference } from '@endo/common/list-difference.js';
49
import {
510
assertChecker,
611
Far,
@@ -9,19 +14,16 @@ import {
914
passStyleOf,
1015
hasOwnPropertyOf,
1116
nameForPassableSymbol,
17+
} from '@endo/pass-style';
18+
import {
1219
compareRank,
1320
getPassStyleCover,
1421
intersectRankCovers,
1522
unionRankCovers,
1623
recordNames,
1724
recordValues,
1825
} from '@endo/marshal';
19-
import { identChecker } from '@endo/common/ident-checker.js';
20-
import { applyLabelingError } from '@endo/common/apply-labeling-error.js';
21-
import { fromUniqueEntries } from '@endo/common/from-unique-entries.js';
22-
import { listDifference } from '@endo/common/list-difference.js';
2326

24-
import { q, b, X, Fail, makeError, annotateError } from '@endo/errors';
2527
import { keyEQ, keyGT, keyGTE, keyLT, keyLTE } from '../keys/compareKeys.js';
2628
import {
2729
assertKey,
@@ -34,6 +36,8 @@ import {
3436
checkCopyBag,
3537
getCopyMapEntryArray,
3638
makeCopyMap,
39+
makeCopySet,
40+
makeCopyBag,
3741
} from '../keys/checkKey.js';
3842
import { generateCollectionPairEntries } from '../keys/keycollection-operators.js';
3943

@@ -1311,8 +1315,8 @@ const makePatternKit = () => {
13111315
* @param {bigint} bound Must be >= 1n
13121316
* @param {CopyArray<[Key, bigint]>} [inResults]
13131317
* @param {CopyArray<[Key, bigint]>} [outResults]
1314-
* @returns {boolean}
13151318
* @param {Checker} [check]
1319+
* @returns {boolean}
13161320
*/
13171321
const pairsHasSplit = (
13181322
pairs,
@@ -1330,7 +1334,7 @@ const makePatternKit = () => {
13301334
// results. It is more intuitive for the choice to be the first `bound`
13311335
// matching elements in ascending lexicigraphic order, rather than
13321336
// decending. Thus we iterate `pairs` in reverse order.
1333-
for (let i = pairs.length - 1; i >= 0n; i -= 1) {
1337+
for (let i = pairs.length - 1; i >= 0; i -= 1) {
13341338
const [element, num] = pairs[i];
13351339
const numRest = bound - count;
13361340
if (numRest >= 1n) {
@@ -1359,6 +1363,87 @@ const makePatternKit = () => {
13591363
);
13601364
};
13611365

1366+
/**
1367+
* @typedef {CopyArray | CopySet | CopyBag} CopyStuff
1368+
* @typedef {CopyTagged<'match:has'>} CopyStuffHasBound
1369+
* @param {CopyStuff} specimen
1370+
* @param {Pattern} elementPatt
1371+
* @param {bigint} bound Must be >= 1n
1372+
* @param {boolean} [needInResults]
1373+
* @param {boolean} [needOutResults]
1374+
* @param {Checker} [check]
1375+
* @returns {[CopyStuff | undefined, CopyStuff | undefined] | false}
1376+
*/
1377+
const copyStuffHasSplit = (
1378+
specimen,
1379+
elementPatt,
1380+
bound,
1381+
needInResults = false,
1382+
needOutResults = false,
1383+
check = identChecker,
1384+
) => {
1385+
const inResults = needInResults ? [] : undefined;
1386+
const outResults = needOutResults ? [] : undefined;
1387+
const kind = kindOf(specimen);
1388+
switch (kind) {
1389+
case 'copyArray': {
1390+
if (
1391+
!elementsHasSplit(
1392+
specimen,
1393+
elementPatt,
1394+
bound,
1395+
inResults,
1396+
outResults,
1397+
check,
1398+
)
1399+
) {
1400+
// check logic already performed by elementsHasSplit
1401+
return false;
1402+
}
1403+
return [inResults, outResults];
1404+
}
1405+
case 'copySet': {
1406+
if (
1407+
!elementsHasSplit(
1408+
specimen.payload,
1409+
elementPatt,
1410+
bound,
1411+
inResults,
1412+
outResults,
1413+
check,
1414+
)
1415+
) {
1416+
return false;
1417+
}
1418+
return [
1419+
inResults && makeCopySet(inResults),
1420+
inResults && makeCopySet(inResults),
1421+
];
1422+
}
1423+
case 'copyBag': {
1424+
if (
1425+
!pairsHasSplit(
1426+
specimen.payload,
1427+
elementPatt,
1428+
bound,
1429+
inResults,
1430+
outResults,
1431+
check,
1432+
)
1433+
) {
1434+
return false;
1435+
}
1436+
return [
1437+
inResults && makeCopyBag(inResults),
1438+
inResults && makeCopyBag(inResults),
1439+
];
1440+
}
1441+
default: {
1442+
return check(false, X`unexpected ${q(kind)}`);
1443+
}
1444+
}
1445+
};
1446+
13621447
/** @type {MatchHelper} */
13631448
const matchHasHelper = Far('match:has helper', {
13641449
/**
@@ -1382,41 +1467,14 @@ const makePatternKit = () => {
13821467
) {
13831468
return false;
13841469
}
1385-
switch (kind) {
1386-
case 'copyArray': {
1387-
return elementsHasSplit(
1388-
specimen,
1389-
elementPatt,
1390-
bound,
1391-
undefined,
1392-
undefined,
1393-
check,
1394-
);
1395-
}
1396-
case 'copySet': {
1397-
return elementsHasSplit(
1398-
specimen.payload,
1399-
elementPatt,
1400-
bound,
1401-
undefined,
1402-
undefined,
1403-
check,
1404-
);
1405-
}
1406-
case 'copyBag': {
1407-
return pairsHasSplit(
1408-
specimen.payload,
1409-
elementPatt,
1410-
bound,
1411-
undefined,
1412-
undefined,
1413-
check,
1414-
);
1415-
}
1416-
default: {
1417-
return check(false, X`unexpected ${q(kind)}`);
1418-
}
1419-
}
1470+
return !!copyStuffHasSplit(
1471+
specimen,
1472+
elementPatt,
1473+
bound,
1474+
false,
1475+
false,
1476+
check,
1477+
);
14201478
},
14211479

14221480
checkIsWellFormed: (payload, check) =>
@@ -1938,8 +1996,7 @@ const makePatternKit = () => {
19381996
getRankCover,
19391997
M,
19401998
kindOf,
1941-
elementsHasSplit,
1942-
pairsHasSplit,
1999+
copyStuffHasSplit,
19432000
});
19442001
};
19452002

@@ -1958,8 +2015,7 @@ export const {
19582015
getRankCover,
19592016
M,
19602017
kindOf,
1961-
elementsHasSplit,
1962-
pairsHasSplit,
2018+
copyStuffHasSplit,
19632019
} = makePatternKit();
19642020

19652021
MM = M;

0 commit comments

Comments
 (0)