UNPKG

@informalsystems/quint

Version:

Core tool for the Quint specification language

90 lines 3.29 kB
"use strict"; 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