@informalsystems/quint
Version:
Core tool for the Quint specification language
90 lines • 3.29 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseMockedModule = exports.quintExAreEqual = exports.collectIds = void 0;
const chai_1 = require("chai");
const IRVisitor_1 = require("../src/ir/IRVisitor");
const util_1 = require("../src/util");
const quintParserFrontend_1 = require("../src/parsing/quintParserFrontend");
const idGenerator_1 = require("../src/idGenerator");
function collectIds(module) {
const ids = new Set();
const visitor = {
exitDecl: (decl) => {
ids.add(decl.id);
},
exitExpr(e) {
ids.add(e.id);
},
exitTypeDef(t) {
ids.add(t.id);
},
exitType(t) {
if (t.id) {
ids.add(t.id);
}
},
exitModule(m) {
ids.add(m.id);
},
exitLambda(l) {
l.params.forEach(p => ids.add(p.id));
},
exitLet(l) {
ids.add(l.opdef.id);
},
exitInstance(i) {
i.overrides.forEach(([n, _]) => ids.add(n.id));
},
};
(0, IRVisitor_1.walkModule)(visitor, module);
return [...ids];
}
exports.collectIds = collectIds;
// Type predicate that tells us when a QuintEx is a scalar with a `value`
function isScalar(v) {
return v.kind === 'bool' || v.kind === 'int' || v.kind === 'str';
}
/** `quinExAreEqual(a, b)` is `true` when the expressions `a` and `b` are structurally equal, modulo ids
*
* This tells us whether `a` and `b` represent the same expression,
* irrespective of when or where they were constructed.
*/
function quintExAreEqual(a, b) {
if (a.kind !== b.kind) {
return false;
}
// The repeated checks on `kind` are for type narrowing
if (a.kind === 'name' && b.kind === 'name') {
return a.name === b.name;
}
else if (isScalar(a) && isScalar(b)) {
return a.value === b.value;
}
else if (a.kind === 'app' && b.kind === 'app') {
return a.args.length === b.args.length && (0, util_1.zip)(a.args, b.args).every(([x, y]) => quintExAreEqual(x, y));
}
else if (a.kind === 'lambda' && b.kind === 'lambda') {
return (a.qualifier === b.qualifier &&
a.params.length === b.params.length &&
(0, util_1.zip)(a.params, b.params).every(([x, y]) => x.name === y.name) &&
quintExAreEqual(a.expr, b.expr));
}
else if (a.kind === 'let' && b.kind === 'let') {
return a.opdef.name === b.opdef.name && a.opdef.qualifier === b.opdef.qualifier && quintExAreEqual(a.expr, b.expr);
}
else {
throw new Error(`internal error: case not handeled for quintExAreEqual over ${a.kind}`);
}
}
exports.quintExAreEqual = quintExAreEqual;
function parseMockedModule(text) {
const idGen = (0, idGenerator_1.newIdGenerator)();
const fake_path = { normalizedPath: 'fake_path', toSourceName: () => 'fake_path' };
const parseResult = (0, quintParserFrontend_1.parse)(idGen, 'fake_location', fake_path, text);
// We use deepEqual instead of `isEmpty` so we'll get informative
// output on failure.
chai_1.assert.deepEqual([], parseResult.errors);
return parseResult;
}
exports.parseMockedModule = parseMockedModule;
//# sourceMappingURL=util.js.map