|
| 1 | +# Arithmetic Expressions |
| 2 | + |
| 3 | +||| |
| 4 | +|---|--- |
| 5 | +| **JEP** | 16 |
| 6 | +| **Author** | Maxime Labelle |
| 7 | +| **Created**| 01-August-2022 |
| 8 | +| **SemVer** | MINOR |
| 9 | +| **Status** | Draft |
| 10 | + |
| 11 | +## Abstract |
| 12 | + |
| 13 | +This JEP proposes a new `arithmetic-expression` rule in the grammar to support simple arithmetic operations. |
| 14 | + |
| 15 | +## Motivation |
| 16 | + |
| 17 | +JMESPath supports querying JSON documents that may return numbers at various stages, but lacks the capability to operate on them using simple arithmetic operations. The only support for arithmetic is currently brought by the `sum()` function. |
| 18 | + |
| 19 | +## Specification |
| 20 | + |
| 21 | +To support arithmetic operations, we need to introduce the following operators: |
| 22 | + |
| 23 | +- `+` addition operator |
| 24 | +- `-` subtraction operator |
| 25 | +- `*` multiplication operator |
| 26 | +- `/` division operator |
| 27 | +- `%` modulo operator |
| 28 | +- `//` integer division operator |
| 29 | + |
| 30 | +Proper mathematical operators also exist in Unicode and SHOULD be supported: |
| 31 | + |
| 32 | +- `–` (U+2212 MINUS SIGN) |
| 33 | +- `÷` (U+00F7 DIVISION SIGN) |
| 34 | +- `×` (U+00D7 MULTIPLY SIGN) |
| 35 | + |
| 36 | +### Syntax changes |
| 37 | + |
| 38 | +In addition to the following grammar changes, we introduce the usual operator precedence, from lowest to highest: |
| 39 | + |
| 40 | +- `-` subtraction operator and `+` addition operator |
| 41 | +- `/` division, `*` multiplication, `%` modulo and `//` integer division operators |
| 42 | + |
| 43 | +In the absence of parentheses, operators of the same level of precedence are evaluated from left to right. |
| 44 | + |
| 45 | +Arithmetic operators have higher precedence than comparison operators and lower precedence than the `.` "dot" `sub-expression` token separator. |
| 46 | + |
| 47 | +```abnf |
| 48 | +expression =/ arithmetic-expression |
| 49 | +
|
| 50 | +arithmetic-expression =/ "+" expression ; + %x43 |
| 51 | +arithmetic-expression =/ ( "-" / "–" ) expression ; - %x45 – %x2212 |
| 52 | +
|
| 53 | +arithmetic-expression = expression "%" expression ; % %x37 |
| 54 | +arithmetic-expression =/ expression ( "*" / "×" ) expression ; * %x42 × %xD7 |
| 55 | +arithmetic-expression =/ expression "+" expression ; + %x43 |
| 56 | +arithmetic-expression =/ expression ( "-" / "–" ) expression ; - %x45 – %x2212 |
| 57 | +arithmetic-expression =/ expression ( "/" / "÷" ) expression ; / %x47 ÷ %xF7 |
| 58 | +arithmetic-expression = expression "//" expression ; // %47 %47 |
| 59 | +
|
| 60 | +``` |
| 61 | + |
| 62 | +## Examples |
| 63 | + |
| 64 | +|Expression|Result |
| 65 | +|---|--- |
| 66 | +|`` `1` + `2` ``| `3.0` |
| 67 | +|`` `1` – `2` ``| `-1.0` |
| 68 | +|`` `2` × `4` ``| `8.0` |
| 69 | +|`` `2` ÷ `3` ``| `0.666666666666667` |
| 70 | +|`` `10` % `3` ``| `1.0` |
| 71 | +|`` `10` // `3` ``| `3.0` |
| 72 | +|`` -`1` − +`2` ``| `-3.0` |
| 73 | + |
| 74 | +Since `arithmetic-expression` is not valid on the right-hand-side of a `sub-expression`, a `pipe-expression` can be used instead: |
| 75 | + |
| 76 | +|Given|Expression|Result |
| 77 | +|---|---|--- |
| 78 | +|`{ "a": { "b": 1 }, "c": { "d": 2 } }`|`` { ab: a.b, cd: c.d } \| ab + cd ``| `3` |
| 79 | + |
| 80 | +## Compliance Tests |
| 81 | + |
| 82 | +An `arithmetic.json` file will be added to the compliance test suite. |
| 83 | +The test suite will add the following new error type: |
| 84 | + |
| 85 | +- not-a-number |
| 86 | + |
| 87 | +This error type would be raised at run time when dividing by zero or when overflow occurs, for instance. |
0 commit comments