Skip to content

Commit b15904f

Browse files
authored
fix: #3579 conditional parsed as optional chaining (#3584)
1 parent 6cb374d commit b15904f

File tree

2 files changed

+11
-1
lines changed

2 files changed

+11
-1
lines changed

src/expression/parse.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,13 @@ export const createParse = /* #__PURE__ */ factory(name, dependencies, ({
322322
}
323323

324324
// check for delimiters consisting of 2 characters
325-
if (c2.length === 2 && DELIMITERS[c2]) {
325+
// Special case: the check for '?.' is to prevent a case like 'a?.3:.7' from being interpreted as optional chaining
326+
// TODO: refactor the tokenization into some better way to deal with cases like 'a?.3:.7', see https://github.com/josdejong/mathjs/pull/3584
327+
if (
328+
c2.length === 2 &&
329+
DELIMITERS[c2] &&
330+
(c2 !== '?.' || !parse.isDigit(state.expression.charAt(state.index + 2)))
331+
) {
326332
state.tokenType = TOKENTYPE.DELIMITER
327333
state.token = c2
328334
next(state)

test/unit-tests/expression/parse.test.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2185,6 +2185,10 @@ describe('parse', function () {
21852185
assert.strictEqual(parseAndEval('0 > 0 ? 1 : 0 < 0 ? -1 : 0'), 0)
21862186
})
21872187

2188+
it('should parse a conditional operator and not optional chaining when followed by a number', function () {
2189+
assert.strictEqual(parseAndEval('true?.3:.7'), 0.3)
2190+
})
2191+
21882192
it('should lazily evaluate conditional expression a ? b : c', function () {
21892193
const scope = {}
21902194
math.parse('true ? (a = 2) : (b = 2)').compile().evaluate(scope)

0 commit comments

Comments
 (0)