simple-graph-query 2.7.2 → 2.8.1
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.
|
@@ -48590,7 +48590,7 @@ function bitwidthWraparound(value, bitwidth) {
|
|
|
48590
48590
|
// this is a list of forge builtin functions we currently support; add to this
|
|
48591
48591
|
// list as we support more
|
|
48592
48592
|
const SUPPORTED_BINARY_BUILTINS = ["add", "subtract", "multiply", "divide", "remainder"];
|
|
48593
|
-
const SUPPORTED_UNARY_BUILTINS = ["abs", "sign"];
|
|
48593
|
+
const SUPPORTED_UNARY_BUILTINS = ["abs", "sign", "floor", "ceil"];
|
|
48594
48594
|
const SUPPORTED_SET_BUILTINS = ["min", "max"];
|
|
48595
48595
|
exports.SUPPORTED_BUILTINS = SUPPORTED_BINARY_BUILTINS.concat(SUPPORTED_UNARY_BUILTINS, SUPPORTED_SET_BUILTINS);
|
|
48596
48596
|
/**
|
|
@@ -48987,6 +48987,46 @@ class ForgeExprEvaluator extends AbstractParseTreeVisitor_1.AbstractParseTreeVis
|
|
|
48987
48987
|
varNames.push(varName);
|
|
48988
48988
|
quantifiedSets.push(varQuantifiedSets[varName]);
|
|
48989
48989
|
}
|
|
48990
|
+
// `sum <decls> | <intExpr>`: accumulate the numeric body over every
|
|
48991
|
+
// binding of the quantified variables. Unlike the boolean quantifiers
|
|
48992
|
+
// below, the body evaluates to a number, so this needs its own loop --
|
|
48993
|
+
// and it must not use the boolean numeric-comparison optimization, which
|
|
48994
|
+
// skips body evaluation entirely.
|
|
48995
|
+
if (ctx.quant().SUM_TOK()) {
|
|
48996
|
+
const sumCombinations = getCombinations(quantifiedSets);
|
|
48997
|
+
const sumEnv = { env: {}, type: "quantDecl" };
|
|
48998
|
+
this.environmentStack.push(sumEnv);
|
|
48999
|
+
let total = 0;
|
|
49000
|
+
for (const tuple of sumCombinations) {
|
|
49001
|
+
if (isDisjoint) {
|
|
49002
|
+
const seen = new Set();
|
|
49003
|
+
let tupleDisjoint = true;
|
|
49004
|
+
for (const val of tuple) {
|
|
49005
|
+
if (seen.has(val)) {
|
|
49006
|
+
tupleDisjoint = false;
|
|
49007
|
+
break;
|
|
49008
|
+
}
|
|
49009
|
+
seen.add(val);
|
|
49010
|
+
}
|
|
49011
|
+
if (!tupleDisjoint) {
|
|
49012
|
+
continue;
|
|
49013
|
+
}
|
|
49014
|
+
}
|
|
49015
|
+
for (let j = 0; j < varNames.length; j++) {
|
|
49016
|
+
sumEnv.env[varNames[j]] = tuple[j];
|
|
49017
|
+
}
|
|
49018
|
+
const bodyValue = this.visit(barExpr);
|
|
49019
|
+
const bodyNumber = extractNumber(bodyValue);
|
|
49020
|
+
if (bodyNumber === undefined) {
|
|
49021
|
+
this.environmentStack.pop();
|
|
49022
|
+
throw new Error("Expected the expression after the bar in a `sum` to evaluate to a number!");
|
|
49023
|
+
}
|
|
49024
|
+
total += bodyNumber;
|
|
49025
|
+
}
|
|
49026
|
+
this.environmentStack.pop();
|
|
49027
|
+
this.cacheResult(ctx, freeVarsKey, total);
|
|
49028
|
+
return total;
|
|
49029
|
+
}
|
|
48990
49030
|
// Try to optimize numeric comparisons
|
|
48991
49031
|
let product;
|
|
48992
49032
|
let useOptimizedPath = false;
|
|
@@ -49133,7 +49173,8 @@ class ForgeExprEvaluator extends AbstractParseTreeVisitor_1.AbstractParseTreeVis
|
|
|
49133
49173
|
return value;
|
|
49134
49174
|
}
|
|
49135
49175
|
}
|
|
49136
|
-
//
|
|
49176
|
+
// NOTE: SUM_TOK is handled above (it returns a number, not a boolean),
|
|
49177
|
+
// before this boolean-quantifier result logic.
|
|
49137
49178
|
}
|
|
49138
49179
|
// TODO: fix this!
|
|
49139
49180
|
const childrenResults = this.visitChildren(ctx);
|
|
@@ -50367,7 +50408,7 @@ class ForgeExprEvaluator extends AbstractParseTreeVisitor_1.AbstractParseTreeVis
|
|
|
50367
50408
|
result = arg1 * arg2;
|
|
50368
50409
|
break;
|
|
50369
50410
|
case "divide":
|
|
50370
|
-
result =
|
|
50411
|
+
result = arg1 / arg2; // Real (floating-point) division
|
|
50371
50412
|
break;
|
|
50372
50413
|
case "remainder":
|
|
50373
50414
|
result = arg1 % arg2;
|
|
@@ -50378,17 +50419,17 @@ class ForgeExprEvaluator extends AbstractParseTreeVisitor_1.AbstractParseTreeVis
|
|
|
50378
50419
|
return result;
|
|
50379
50420
|
}
|
|
50380
50421
|
evaluateUnaryOperation(operation, args) {
|
|
50381
|
-
|
|
50422
|
+
const v = extractNumber(args);
|
|
50423
|
+
if (v === undefined) {
|
|
50382
50424
|
throw new Error(`Expected 1 argument for ${operation} that evaluates to a number.`);
|
|
50383
50425
|
}
|
|
50384
|
-
let v = args;
|
|
50385
50426
|
// Possible unary operations:
|
|
50386
|
-
//abs[]:
|
|
50387
|
-
//sign[]:
|
|
50427
|
+
//abs[]: returns the absolute value of value
|
|
50428
|
+
//sign[]: returns 1 if value is > 0, 0 if value is 0, and -1 if value is < 0
|
|
50429
|
+
//floor[]: rounds value down to the nearest integer
|
|
50430
|
+
//ceil[]: rounds value up to the nearest integer
|
|
50388
50431
|
if (operation === "abs") {
|
|
50389
|
-
|
|
50390
|
-
// Now adjust to the bitwidth
|
|
50391
|
-
return res;
|
|
50432
|
+
return Math.abs(v);
|
|
50392
50433
|
}
|
|
50393
50434
|
else if (operation === "sign") {
|
|
50394
50435
|
if (v > 0) {
|
|
@@ -50401,6 +50442,12 @@ class ForgeExprEvaluator extends AbstractParseTreeVisitor_1.AbstractParseTreeVis
|
|
|
50401
50442
|
return 0;
|
|
50402
50443
|
}
|
|
50403
50444
|
}
|
|
50445
|
+
else if (operation === "floor") {
|
|
50446
|
+
return Math.floor(v);
|
|
50447
|
+
}
|
|
50448
|
+
else if (operation === "ceil") {
|
|
50449
|
+
return Math.ceil(v);
|
|
50450
|
+
}
|
|
50404
50451
|
else {
|
|
50405
50452
|
throw new Error(`Unsupported operation: ${operation}`);
|
|
50406
50453
|
}
|
package/package.json
CHANGED