@sdeverywhere/parse 0.1.0 → 0.1.2
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/dist/index.cjs +100 -31
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +117 -1
- package/dist/index.d.ts +117 -1
- package/dist/index.js +96 -31
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -29,11 +29,15 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
29
29
|
// src/index.ts
|
|
30
30
|
var src_exports = {};
|
|
31
31
|
__export(src_exports, {
|
|
32
|
+
canonicalFunctionId: () => canonicalFunctionId,
|
|
33
|
+
canonicalId: () => canonicalId,
|
|
34
|
+
canonicalVarId: () => canonicalVarId,
|
|
32
35
|
debugPrintExpr: () => debugPrintExpr,
|
|
33
36
|
parseVensimEquation: () => parseVensimEquation,
|
|
34
37
|
parseVensimExpr: () => parseVensimExpr,
|
|
35
38
|
parseVensimModel: () => parseVensimModel,
|
|
36
39
|
parseVensimSubscriptRange: () => parseVensimSubscriptRange,
|
|
40
|
+
preprocessVensimModel: () => preprocessVensimModel,
|
|
37
41
|
prettyPrintExpr: () => prettyPrintExpr,
|
|
38
42
|
printExprStats: () => printExprStats,
|
|
39
43
|
reduceConditionals: () => reduceConditionals,
|
|
@@ -42,6 +46,29 @@ __export(src_exports, {
|
|
|
42
46
|
});
|
|
43
47
|
module.exports = __toCommonJS(src_exports);
|
|
44
48
|
|
|
49
|
+
// src/_shared/canonical-id.js
|
|
50
|
+
var reTrailingMark = new RegExp("\\s+!$", "g");
|
|
51
|
+
var reWhitespace = new RegExp("(\\s|_)+", "g");
|
|
52
|
+
var reSpecialChars = new RegExp(`['"\\.,\\-\\$&%\\/\\|()]`, "g");
|
|
53
|
+
function canonicalId(name) {
|
|
54
|
+
return "_" + name.trim().replace(reTrailingMark, "!").replace(reWhitespace, "_").replace(reSpecialChars, "_").toLowerCase();
|
|
55
|
+
}
|
|
56
|
+
function canonicalVarId(name) {
|
|
57
|
+
const m = name.match(/([^[]+)(?:\[([^\]]+)\])?/);
|
|
58
|
+
if (!m) {
|
|
59
|
+
throw new Error(`Invalid variable name: ${name}`);
|
|
60
|
+
}
|
|
61
|
+
let id = canonicalId(m[1]);
|
|
62
|
+
if (m[2]) {
|
|
63
|
+
const subscripts = m[2].split(",").map((x) => canonicalId(x));
|
|
64
|
+
id += `[${subscripts.join(",")}]`;
|
|
65
|
+
}
|
|
66
|
+
return id;
|
|
67
|
+
}
|
|
68
|
+
function canonicalFunctionId(name) {
|
|
69
|
+
return canonicalId(name).toUpperCase();
|
|
70
|
+
}
|
|
71
|
+
|
|
45
72
|
// src/ast/print-expr.ts
|
|
46
73
|
var import_assert_never = require("assert-never");
|
|
47
74
|
function debugPrintExpr(expr, indent = 0) {
|
|
@@ -290,14 +317,6 @@ function fullIdForVarRef(varRef) {
|
|
|
290
317
|
// src/ast/reduce-expr.ts
|
|
291
318
|
var import_assert_never2 = require("assert-never");
|
|
292
319
|
|
|
293
|
-
// src/_shared/names.js
|
|
294
|
-
function canonicalName(name) {
|
|
295
|
-
return "_" + name.trim().replace(/"/g, "_").replace(/\s+!$/g, "!").replace(/\s/g, "_").replace(/,/g, "_").replace(/-/g, "_").replace(/\./g, "_").replace(/\$/g, "_").replace(/'/g, "_").replace(/&/g, "_").replace(/%/g, "_").replace(/\//g, "_").replace(/\|/g, "_").toLowerCase();
|
|
296
|
-
}
|
|
297
|
-
function cFunctionName(name) {
|
|
298
|
-
return canonicalName(name).toUpperCase();
|
|
299
|
-
}
|
|
300
|
-
|
|
301
320
|
// src/ast/ast-builders.ts
|
|
302
321
|
function num(value, text) {
|
|
303
322
|
return {
|
|
@@ -673,7 +692,7 @@ var SubscriptRangeReader = class extends import_antlr4_vensim2.ModelVisitor {
|
|
|
673
692
|
const ids = ctx.Id();
|
|
674
693
|
if (ids.length === 1) {
|
|
675
694
|
const dimName = ids[0].getText();
|
|
676
|
-
const dimId =
|
|
695
|
+
const dimId = canonicalId(dimName);
|
|
677
696
|
super.visitSubscriptRange(ctx);
|
|
678
697
|
return {
|
|
679
698
|
dimName,
|
|
@@ -683,7 +702,7 @@ var SubscriptRangeReader = class extends import_antlr4_vensim2.ModelVisitor {
|
|
|
683
702
|
subscriptRefs: this.subscriptNames.map((subName) => {
|
|
684
703
|
return {
|
|
685
704
|
subName,
|
|
686
|
-
subId:
|
|
705
|
+
subId: canonicalId(subName)
|
|
687
706
|
};
|
|
688
707
|
}),
|
|
689
708
|
subscriptMappings: this.subscriptMappings,
|
|
@@ -691,9 +710,9 @@ var SubscriptRangeReader = class extends import_antlr4_vensim2.ModelVisitor {
|
|
|
691
710
|
};
|
|
692
711
|
} else if (ids.length === 2) {
|
|
693
712
|
const dimName = ids[0].getText();
|
|
694
|
-
const dimId =
|
|
713
|
+
const dimId = canonicalId(dimName);
|
|
695
714
|
const familyName = ids[1].getText();
|
|
696
|
-
const familyId =
|
|
715
|
+
const familyId = canonicalId(familyName);
|
|
697
716
|
return {
|
|
698
717
|
dimName,
|
|
699
718
|
dimId,
|
|
@@ -733,11 +752,11 @@ var SubscriptRangeReader = class extends import_antlr4_vensim2.ModelVisitor {
|
|
|
733
752
|
super.visitSubscriptMapping(ctx);
|
|
734
753
|
this.subscriptMappings.push({
|
|
735
754
|
toDimName,
|
|
736
|
-
toDimId:
|
|
755
|
+
toDimId: canonicalId(toDimName),
|
|
737
756
|
subscriptRefs: this.mappedSubscriptNames.map((subName) => {
|
|
738
757
|
return {
|
|
739
758
|
subName,
|
|
740
|
-
subId:
|
|
759
|
+
subId: canonicalId(subName)
|
|
741
760
|
};
|
|
742
761
|
})
|
|
743
762
|
});
|
|
@@ -747,7 +766,7 @@ var SubscriptRangeReader = class extends import_antlr4_vensim2.ModelVisitor {
|
|
|
747
766
|
}
|
|
748
767
|
visitCall(ctx) {
|
|
749
768
|
const fnName = ctx.Id().getText();
|
|
750
|
-
const fnId =
|
|
769
|
+
const fnId = canonicalFunctionId(fnName);
|
|
751
770
|
if (fnId === "_GET_DIRECT_SUBSCRIPT") {
|
|
752
771
|
super.visitCall(ctx);
|
|
753
772
|
} else {
|
|
@@ -843,7 +862,7 @@ var ExprReader = class extends import_antlr4_vensim3.ModelVisitor {
|
|
|
843
862
|
//
|
|
844
863
|
visitCall(ctx) {
|
|
845
864
|
const vensimFnName = ctx.Id().getText();
|
|
846
|
-
const fnId =
|
|
865
|
+
const fnId = canonicalFunctionId(vensimFnName);
|
|
847
866
|
this.callStack.push({ fn: fnId, args: [] });
|
|
848
867
|
super.visitCall(ctx);
|
|
849
868
|
const callInfo = this.callStack.pop();
|
|
@@ -866,14 +885,14 @@ var ExprReader = class extends import_antlr4_vensim3.ModelVisitor {
|
|
|
866
885
|
}
|
|
867
886
|
visitVar(ctx) {
|
|
868
887
|
const vensimVarName = ctx.Id().getText().trim();
|
|
869
|
-
const varId =
|
|
888
|
+
const varId = canonicalId(vensimVarName);
|
|
870
889
|
this.subscripts = void 0;
|
|
871
890
|
super.visitVar(ctx);
|
|
872
891
|
const subscriptNames = this.subscripts;
|
|
873
892
|
const subscriptRefs = subscriptNames?.map((name) => {
|
|
874
893
|
return {
|
|
875
894
|
subName: name,
|
|
876
|
-
subId:
|
|
895
|
+
subId: canonicalId(name)
|
|
877
896
|
};
|
|
878
897
|
});
|
|
879
898
|
this.subscripts = void 0;
|
|
@@ -923,7 +942,7 @@ var ExprReader = class extends import_antlr4_vensim3.ModelVisitor {
|
|
|
923
942
|
}
|
|
924
943
|
visitLookupCall(ctx) {
|
|
925
944
|
const lookupVarName = ctx.Id().getText();
|
|
926
|
-
const lookupVarId =
|
|
945
|
+
const lookupVarId = canonicalId(lookupVarName);
|
|
927
946
|
if (ctx.subscriptList()) {
|
|
928
947
|
ctx.subscriptList().accept(this);
|
|
929
948
|
}
|
|
@@ -931,7 +950,7 @@ var ExprReader = class extends import_antlr4_vensim3.ModelVisitor {
|
|
|
931
950
|
const subscriptRefs = subscriptNames?.map((name) => {
|
|
932
951
|
return {
|
|
933
952
|
subName: name,
|
|
934
|
-
subId:
|
|
953
|
+
subId: canonicalId(name)
|
|
935
954
|
};
|
|
936
955
|
});
|
|
937
956
|
this.subscripts = void 0;
|
|
@@ -1128,13 +1147,13 @@ var EquationReader = class extends import_antlr4_vensim4.ModelVisitor {
|
|
|
1128
1147
|
}
|
|
1129
1148
|
visitLhs(ctx) {
|
|
1130
1149
|
const lhsVarName = ctx.Id().getText();
|
|
1131
|
-
const lhsVarId =
|
|
1150
|
+
const lhsVarId = canonicalId(lhsVarName);
|
|
1132
1151
|
super.visitLhs(ctx);
|
|
1133
1152
|
const subscriptNames = this.subscripts;
|
|
1134
1153
|
const subscriptRefs = subscriptNames?.map((name) => {
|
|
1135
1154
|
return {
|
|
1136
1155
|
subName: name,
|
|
1137
|
-
subId:
|
|
1156
|
+
subId: canonicalId(name)
|
|
1138
1157
|
};
|
|
1139
1158
|
});
|
|
1140
1159
|
const exceptSubscriptSets = this.exceptSubscriptSets;
|
|
@@ -1142,7 +1161,7 @@ var EquationReader = class extends import_antlr4_vensim4.ModelVisitor {
|
|
|
1142
1161
|
return subscriptSet.map((name) => {
|
|
1143
1162
|
return {
|
|
1144
1163
|
subName: name,
|
|
1145
|
-
subId:
|
|
1164
|
+
subId: canonicalId(name)
|
|
1146
1165
|
};
|
|
1147
1166
|
});
|
|
1148
1167
|
});
|
|
@@ -1222,16 +1241,41 @@ function parseVensimEquation(input) {
|
|
|
1222
1241
|
|
|
1223
1242
|
// src/vensim/preprocess-vensim.ts
|
|
1224
1243
|
var import_split_string = __toESM(require("split-string"), 1);
|
|
1225
|
-
function preprocessVensimModel(input) {
|
|
1244
|
+
function preprocessVensimModel(input, options) {
|
|
1245
|
+
const removalKeys = options?.removalKeys;
|
|
1246
|
+
function shouldRemove(text) {
|
|
1247
|
+
if (text.includes("TABBED ARRAY")) {
|
|
1248
|
+
return true;
|
|
1249
|
+
}
|
|
1250
|
+
if (removalKeys) {
|
|
1251
|
+
for (const key of removalKeys) {
|
|
1252
|
+
if (text.includes(key)) {
|
|
1253
|
+
return true;
|
|
1254
|
+
}
|
|
1255
|
+
}
|
|
1256
|
+
}
|
|
1257
|
+
return false;
|
|
1258
|
+
}
|
|
1259
|
+
const macrosResult = removeMacros(input);
|
|
1260
|
+
input = macrosResult.processed;
|
|
1226
1261
|
const rawDefs = splitDefs(input);
|
|
1227
1262
|
const vensimDefs = [];
|
|
1263
|
+
const removedBlocks = [];
|
|
1228
1264
|
for (const rawDef of rawDefs) {
|
|
1265
|
+
if (shouldRemove(rawDef.text)) {
|
|
1266
|
+
removedBlocks.push(rawDef.text.trim() + "|");
|
|
1267
|
+
continue;
|
|
1268
|
+
}
|
|
1229
1269
|
const vensimDef = processDef(rawDef);
|
|
1230
1270
|
if (vensimDef) {
|
|
1231
1271
|
vensimDefs.push(vensimDef);
|
|
1232
1272
|
}
|
|
1233
1273
|
}
|
|
1234
|
-
return
|
|
1274
|
+
return {
|
|
1275
|
+
defs: vensimDefs,
|
|
1276
|
+
removedMacros: macrosResult.removed,
|
|
1277
|
+
removedBlocks
|
|
1278
|
+
};
|
|
1235
1279
|
}
|
|
1236
1280
|
function splitDefs(input) {
|
|
1237
1281
|
const defTexts = (0, import_split_string.default)(input, { separator: "|", quotes: ['"'], keep: () => true });
|
|
@@ -1273,6 +1317,9 @@ function splitDefs(input) {
|
|
|
1273
1317
|
function splitLines(input) {
|
|
1274
1318
|
return input.split(/\r\n|\n|\r/);
|
|
1275
1319
|
}
|
|
1320
|
+
function splitExceptInQuoted(input, sep) {
|
|
1321
|
+
return (0, import_split_string.default)(input, { separator: sep, quotes: ['"'] });
|
|
1322
|
+
}
|
|
1276
1323
|
function processBackslashes(input) {
|
|
1277
1324
|
const inputLines = splitLines(input);
|
|
1278
1325
|
let output = "";
|
|
@@ -1318,22 +1365,27 @@ function replaceDelimitedStrings(str, open, close, newStr) {
|
|
|
1318
1365
|
function reduceWhitespace(input) {
|
|
1319
1366
|
return input.replace(/\s\s+/g, " ").trim();
|
|
1320
1367
|
}
|
|
1368
|
+
var reWhitespace2 = new RegExp("(\\s|_)+", "g");
|
|
1321
1369
|
function keyForDef(def) {
|
|
1322
1370
|
let key = def;
|
|
1323
1371
|
key = key.replace(/:INTERPOLATE:/g, "");
|
|
1372
|
+
let kind;
|
|
1324
1373
|
if (key.includes("=")) {
|
|
1374
|
+
kind = "eqn";
|
|
1325
1375
|
key = key.split("=")[0].trim();
|
|
1326
1376
|
} else if (key.includes(":")) {
|
|
1377
|
+
kind = "dim";
|
|
1327
1378
|
key = key.split(":")[0].trim();
|
|
1328
1379
|
} else {
|
|
1380
|
+
kind = "decl";
|
|
1329
1381
|
}
|
|
1382
|
+
key = splitExceptInQuoted(key, "(")[0];
|
|
1330
1383
|
key = key.replace(/"/g, "");
|
|
1331
|
-
key = key.split("(")[0];
|
|
1332
1384
|
key = key.trim();
|
|
1333
|
-
key = key.replace(/\
|
|
1334
|
-
key = key.replace(
|
|
1385
|
+
key = key.replace(/(?<=\[).*?(?=\])/g, (match) => match.replace(/\s/g, ""));
|
|
1386
|
+
key = key.replace(reWhitespace2, "_");
|
|
1335
1387
|
key = key.toLowerCase();
|
|
1336
|
-
return key;
|
|
1388
|
+
return { key, kind };
|
|
1337
1389
|
}
|
|
1338
1390
|
function processDef(rawDef) {
|
|
1339
1391
|
let input = rawDef.text;
|
|
@@ -1351,7 +1403,7 @@ function processDef(rawDef) {
|
|
|
1351
1403
|
${input}`);
|
|
1352
1404
|
}
|
|
1353
1405
|
const rawDefText = reduceWhitespace(parts[0]);
|
|
1354
|
-
const key = keyForDef(rawDefText);
|
|
1406
|
+
const { key, kind } = keyForDef(rawDefText);
|
|
1355
1407
|
const def = `${rawDefText} ~~|`;
|
|
1356
1408
|
const units = reduceWhitespace(parts[1]);
|
|
1357
1409
|
const comment = reduceWhitespace(parts[2]);
|
|
@@ -1359,12 +1411,25 @@ ${input}`);
|
|
|
1359
1411
|
return {
|
|
1360
1412
|
key,
|
|
1361
1413
|
def,
|
|
1414
|
+
kind,
|
|
1362
1415
|
line: rawDef.line,
|
|
1363
1416
|
units,
|
|
1364
1417
|
comment,
|
|
1365
1418
|
...group ? { group } : {}
|
|
1366
1419
|
};
|
|
1367
1420
|
}
|
|
1421
|
+
function removeMacros(input) {
|
|
1422
|
+
const removed = [];
|
|
1423
|
+
const processed = input.replace(/:MACRO:.*:END OF MACRO:/gms, (match) => {
|
|
1424
|
+
removed.push(match);
|
|
1425
|
+
const numBreaks = match.split(/\r\n|\n|\r/gms).length - 1;
|
|
1426
|
+
return numBreaks > 0 ? "\n".repeat(numBreaks) : "";
|
|
1427
|
+
});
|
|
1428
|
+
return {
|
|
1429
|
+
processed,
|
|
1430
|
+
removed
|
|
1431
|
+
};
|
|
1432
|
+
}
|
|
1368
1433
|
|
|
1369
1434
|
// src/vensim/impl/model-reader.js
|
|
1370
1435
|
var import_antlr4_vensim5 = require("antlr4-vensim");
|
|
@@ -1423,7 +1488,7 @@ var ModelReader = class extends import_antlr4_vensim5.ModelVisitor {
|
|
|
1423
1488
|
function parseVensimModel(input, context, sort = false) {
|
|
1424
1489
|
const dimensions = [];
|
|
1425
1490
|
const equations = [];
|
|
1426
|
-
const defs = preprocessVensimModel(input);
|
|
1491
|
+
const { defs } = preprocessVensimModel(input);
|
|
1427
1492
|
if (sort) {
|
|
1428
1493
|
defs.sort((a, b) => {
|
|
1429
1494
|
return a.key < b.key ? -1 : a.key > b.key ? 1 : 0;
|
|
@@ -1476,11 +1541,15 @@ Detail:
|
|
|
1476
1541
|
}
|
|
1477
1542
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1478
1543
|
0 && (module.exports = {
|
|
1544
|
+
canonicalFunctionId,
|
|
1545
|
+
canonicalId,
|
|
1546
|
+
canonicalVarId,
|
|
1479
1547
|
debugPrintExpr,
|
|
1480
1548
|
parseVensimEquation,
|
|
1481
1549
|
parseVensimExpr,
|
|
1482
1550
|
parseVensimModel,
|
|
1483
1551
|
parseVensimSubscriptRange,
|
|
1552
|
+
preprocessVensimModel,
|
|
1484
1553
|
prettyPrintExpr,
|
|
1485
1554
|
printExprStats,
|
|
1486
1555
|
reduceConditionals,
|