Skip to content

Add JSON Logic arithmetic operators (+, -, *, /, %)#3483

Draft
ajpallares wants to merge 4 commits into
pallares/json-logic-evaluatorfrom
pallares/json-logic-arithmetic-operators
Draft

Add JSON Logic arithmetic operators (+, -, *, /, %)#3483
ajpallares wants to merge 4 commits into
pallares/json-logic-evaluatorfrom
pallares/json-logic-arithmetic-operators

Conversation

@ajpallares
Copy link
Copy Markdown
Member

@ajpallares ajpallares commented May 14, 2026

Resolves SDK-4330

Motivation

Extends the JSON Logic operator set with arithmetic so predicates can express counter and sum conditions before the comparison and string operators land.

Summary

  • Implements +, -, *, /, % per the JSON Logic spec, including variadic + / *, the 1-arg numeric-cast form of +, and unary negation via -.
  • All operators return Value.FloatValue(Double) for consistency with the JS reference. looseEq / strictEq already bridge IntValue(n) ↔ FloatValue(n.0), so existing comparisons keep working.
  • Non-numeric operands (ObjectValue, ArrayValue, unparseable strings) coerce to Double.NaN and propagate through arithmetic — the result is FloatValue(NaN), falsy under isTruthy.
  • Division and modulo by zero return Value.Null (deliberate deviation from JS's Infinity / NaN — friendlier for rule authors and matches the engine's "missing value" convention). Documented in the type's KDoc.

Tests

  • ArithmeticOperatorsTest covers each operator (basic, variadic, coercion, NaN propagation, divide/mod by zero, arity errors).
  • EvaluatorTest adds two integration tests through dispatch: var * 2 == 6 and the divide-by-zero → null → falsy flow.

Notes

Stacked on top of #3482. Re-target to main once that lands.

Made with Cursor

Extends the JSON Logic operator set with arithmetic so predicates can
express counter and sum conditions before the comparison and string
operators land.

What's new:

- `+`, `-`, `*`, `/`, `%` per the JSON Logic spec, including variadic
  `+` and `*`, the 1-arg numeric-cast form of `+`, and unary negation
  via `-`. All arithmetic returns `Value.FloatValue(Double)` for
  consistency with the JS reference (which `parseFloat`s every
  operand). `looseEq` and `strictEq` already bridge `IntValue(n) ↔
  FloatValue(n.0)`, so existing comparisons keep working.
- Non-numeric operands (`ObjectValue`, `ArrayValue`, unparseable
  strings) coerce to `Double.NaN` and propagate through arithmetic —
  the result is `FloatValue(NaN)`, falsy under `isTruthy`.
- Division and modulo by zero return `Value.Null` (deliberate
  deviation from JS's `Infinity` / `NaN` — friendlier for rule
  authors and matches the engine's "missing value" convention).
  Documented in the type's KDoc.

Tests:

- `ArithmeticOperatorsTest` covers each operator (basic, variadic,
  coercion, NaN propagation, divide/mod by zero, arity errors).
- `EvaluatorTest` adds two integration tests through dispatch:
  `var * 2 == 6` and the divide-by-zero → null → falsy flow.

Co-authored-by: Cursor <cursoragent@cursor.com>
@ajpallares ajpallares added pr:feat A new feature pr:other and removed pr:feat A new feature labels May 14, 2026
ajpallares and others added 3 commits May 21, 2026 17:52
…nto pallares/json-logic-arithmetic-operators
Follow-up to the merge of `pallares/json-logic-evaluator`. The base
branch routes engine warnings through the module-level `Rules.logger`
now (commit 162574d), so threading a `logger: RulesEngineLogger`
through every operator call is no longer needed.

`ArithmeticOperators.opAdd / opMul / opSub / opDiv / opMod` lose the
trailing `logger` parameter and the corresponding
`Operators.evalArgs(args, vars, logger)` /
`Operators.evalTwo(args, vars, logger, opName)` calls collapse onto
the simpler post-merge signatures. The `RulesEngineLogger` import
goes with them.

Drive-by from the merge auto-resolution: drop the now-stale `, logger`
references the auto-merge left in `Operators.dispatch` for the
arithmetic cases (`+`, `-`, `*`, `/`, `%`).

Test side: `ArithmeticOperatorsTest.run` helper drops its
`PrintlnLogger` argument and the `RulesEngineLogger` typealias on
the function-reference parameter. The arithmetic operators have a
1:1 parity with the iOS counterpart PR (commit `f2d7e084b`) — same
operator set, same NaN-poison + `Null`-on-zero-divisor semantics,
same test coverage — so no new behavior tests are added by this
commit.

Verified: `:rules-engine:testDefaultsDebugUnitTest`, `detektAll`, and
`scripts/check-rules-engine-internal-only.sh` all green.

Co-authored-by: Cursor <cursoragent@cursor.com>
…nto pallares/json-logic-arithmetic-operators
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant