lemmascript 0.5.22 → 0.6.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/package.json +1 -1
- package/tools/dist/dafny-emit.js +10 -18
- package/tools/dist/extract.js +2 -1
- package/tools/dist/lsc.js +7 -1
- package/tools/dist/specparser.js +10 -8
package/package.json
CHANGED
package/tools/dist/dafny-emit.js
CHANGED
|
@@ -1583,10 +1583,8 @@ export function emitDafnyFile(file, tsFileName, opts) {
|
|
|
1583
1583
|
// skipped when the corresponding pure def was actually emitted.
|
|
1584
1584
|
const emittedPureDefs = new Set();
|
|
1585
1585
|
// Emit a decl, rolling back any preamble requirements it registered if it
|
|
1586
|
-
// throws
|
|
1587
|
-
//
|
|
1588
|
-
// preamble (e.g. `type Unknown` from a skipped const whose head is
|
|
1589
|
-
// `unknown`-typed but whose value expr is unsupported).
|
|
1586
|
+
// throws, so callers that catch an emission error never observe partial
|
|
1587
|
+
// emitter state.
|
|
1590
1588
|
const emitDeclTx = (d) => {
|
|
1591
1589
|
const saved = new Set(_neededPreambles);
|
|
1592
1590
|
try {
|
|
@@ -1601,13 +1599,12 @@ export function emitDafnyFile(file, tsFileName, opts) {
|
|
|
1601
1599
|
};
|
|
1602
1600
|
// Emit declarations
|
|
1603
1601
|
const declLines = [];
|
|
1604
|
-
const skipped = [];
|
|
1605
1602
|
for (const decl of file.decls) {
|
|
1606
1603
|
if (decl.kind === "method" && emittedPureDefs.has(decl.name))
|
|
1607
1604
|
continue;
|
|
1608
1605
|
if (decl.kind === "namespace") {
|
|
1609
|
-
// Emit each inner
|
|
1610
|
-
//
|
|
1606
|
+
// Emit each inner declaration separately so failures name the exact
|
|
1607
|
+
// pure declaration that could not be translated.
|
|
1611
1608
|
for (const inner of decl.decls) {
|
|
1612
1609
|
try {
|
|
1613
1610
|
declLines.push("");
|
|
@@ -1617,10 +1614,9 @@ export function emitDafnyFile(file, tsFileName, opts) {
|
|
|
1617
1614
|
}
|
|
1618
1615
|
catch (e) {
|
|
1619
1616
|
const name = "name" in inner ? inner.name : "unknown";
|
|
1620
|
-
const
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
skipped.push(name);
|
|
1617
|
+
const reason = e instanceof Error ? e.message : String(e);
|
|
1618
|
+
const source = tsFileName ? ` in ${tsFileName}` : "";
|
|
1619
|
+
throw new Error(`Dafny emission failed for '${name}'${source}: ${reason}`);
|
|
1624
1620
|
}
|
|
1625
1621
|
}
|
|
1626
1622
|
continue;
|
|
@@ -1633,15 +1629,11 @@ export function emitDafnyFile(file, tsFileName, opts) {
|
|
|
1633
1629
|
}
|
|
1634
1630
|
catch (e) {
|
|
1635
1631
|
const name = "name" in decl ? decl.name : "unknown";
|
|
1636
|
-
const
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
skipped.push(name);
|
|
1632
|
+
const reason = e instanceof Error ? e.message : String(e);
|
|
1633
|
+
const source = tsFileName ? ` in ${tsFileName}` : "";
|
|
1634
|
+
throw new Error(`Dafny emission failed for '${name}'${source}: ${reason}`);
|
|
1640
1635
|
}
|
|
1641
1636
|
}
|
|
1642
|
-
if (skipped.length > 0) {
|
|
1643
|
-
console.error(`WARNING: ${skipped.length} declaration(s) skipped: ${skipped.join(", ")}`);
|
|
1644
|
-
}
|
|
1645
1637
|
// Build output with needed preambles
|
|
1646
1638
|
const lines = [];
|
|
1647
1639
|
if (tsFileName)
|
package/tools/dist/extract.js
CHANGED
|
@@ -2158,7 +2158,8 @@ export function extractModule(sourceFile) {
|
|
|
2158
2158
|
});
|
|
2159
2159
|
}
|
|
2160
2160
|
catch (e) {
|
|
2161
|
-
|
|
2161
|
+
const reason = e instanceof Error ? e.message : String(e);
|
|
2162
|
+
throw new Error(`Failed to extract const '${decl.getName()}' at ${sourceFile.getBaseName()}:${decl.getStartLineNumber()}: ${reason}`);
|
|
2162
2163
|
}
|
|
2163
2164
|
}
|
|
2164
2165
|
}
|
package/tools/dist/lsc.js
CHANGED
|
@@ -337,4 +337,10 @@ function runFile(cmd, filePath, backend, timeLimit, extraFlags, noVerify = false
|
|
|
337
337
|
console.error(`Unknown command: ${cmd}`);
|
|
338
338
|
process.exit(1);
|
|
339
339
|
}
|
|
340
|
-
|
|
340
|
+
try {
|
|
341
|
+
main();
|
|
342
|
+
}
|
|
343
|
+
catch (e) {
|
|
344
|
+
console.error(`ERROR: ${e instanceof Error ? e.message : String(e)}`);
|
|
345
|
+
process.exitCode = 1;
|
|
346
|
+
}
|
package/tools/dist/specparser.js
CHANGED
|
@@ -4,11 +4,11 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { normalizeBigIntLiteral } from "./rawir.js";
|
|
6
6
|
const MULTI_OPS = ["<==>", "==>", "===", "!==", "==", "!=", ">=", "<=", "&&", "||"];
|
|
7
|
-
/**
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
|
|
11
|
-
const
|
|
7
|
+
/** Numeric literals accepted in specs. BigInts are recognized first so their
|
|
8
|
+
* exact value never passes through Number; ordinary numbers additionally
|
|
9
|
+
* allow TypeScript's fractional and exponent forms. */
|
|
10
|
+
const BIGINT_LITERAL = /^(?:(?:0[xX][0-9a-fA-F](?:_?[0-9a-fA-F])*)|(?:0[bB][01](?:_?[01])*)|(?:0[oO][0-7](?:_?[0-7])*)|(?:[0-9](?:_?[0-9])*))n/;
|
|
11
|
+
const NUMBER_LITERAL = /^(?:(?:0[xX][0-9a-fA-F](?:_?[0-9a-fA-F])*)|(?:0[bB][01](?:_?[01])*)|(?:0[oO][0-7](?:_?[0-7])*)|(?:(?:[0-9](?:_?[0-9])*)(?:\.(?:[0-9](?:_?[0-9])*)?)?|\.(?:[0-9](?:_?[0-9])*))(?:[eE][+-]?(?:[0-9](?:_?[0-9])*))?)/;
|
|
12
12
|
function tokenize(input) {
|
|
13
13
|
const tokens = [];
|
|
14
14
|
let i = 0;
|
|
@@ -47,15 +47,17 @@ function tokenize(input) {
|
|
|
47
47
|
tokens.push({ type: "str", value: s });
|
|
48
48
|
continue;
|
|
49
49
|
}
|
|
50
|
-
if (/[0-9]/.test(input[i])) {
|
|
51
|
-
const
|
|
50
|
+
if (/[0-9]/.test(input[i]) || (input[i] === "." && /[0-9]/.test(input[i + 1]))) {
|
|
51
|
+
const rest = input.slice(i);
|
|
52
|
+
const bigintMatch = rest.match(BIGINT_LITERAL);
|
|
53
|
+
const match = bigintMatch ?? rest.match(NUMBER_LITERAL);
|
|
52
54
|
if (!match)
|
|
53
55
|
throw new Error(`Invalid numeric literal at ${i} in: ${input}`);
|
|
54
56
|
const text = match[0];
|
|
55
57
|
i += text.length;
|
|
56
58
|
// The `n` suffix is meaningful, not noise: a BigInt keeps its exact value
|
|
57
59
|
// as a decimal string instead of being rounded into a double.
|
|
58
|
-
if (
|
|
60
|
+
if (bigintMatch)
|
|
59
61
|
tokens.push({ type: "bigint", value: normalizeBigIntLiteral(text) });
|
|
60
62
|
else
|
|
61
63
|
tokens.push({ type: "num", value: Number(text.replace(/_/g, "")) });
|