Skip to content

solve-engine 1.0.2

Choose a tag to compare

@LiamRiddell LiamRiddell released this 12 Aug 12:07
1a8f85a

Markdown list markers are no longer evaluated as arithmetic.

The bug

- 100 + 20 in a document answered -80.

The - is a bullet, but it is also a prefix operator, and nothing stripped the marker before evaluating, so the line was read as negative one hundred plus twenty. That is the worst shape a bug can take: a plausible number where a correct one was expected, with nothing on screen to say it went wrong.

The tell is that the three unordered markers disagreed with each other about the same document:

Line Before Now
- 100 + 20 -80 120
* 100 + 20 error 120
+ 100 + 20 120, by luck 120, by rule
1. 100 + 20 error 120
- [ ] 100 + 20 "a matrix literal cannot be empty" 120
- 100 + 20 -80 120

Only - is also a valid prefix operator, so it was the one marker that could silently produce a number rather than declining.

This is not a regression. It answered -80 in 1.0.0-beta.2, beta.6, 1.0.0 and 1.0.1 alike, checked against all four published versions rather than assumed.

The fix

The lexer already classified these lines as list, and always had. Nothing consumed that classification to trim the marker before evaluating, so the information needed to get this right was sitting there unused.

LineClassification now carries a contentOffset, and both the token stream and the expression text are sliced from it. Deriving them from a single offset is the point rather than an implementation detail: the previous code passed pre-lexed tokens and the raw line text onward, so fixing only one would have left the two describing different lines.

Task-item checkboxes are skipped as well, guarded so that a real matrix literal is never mistaken for one.

What is unchanged

The discriminator is the space, which CommonMark requires after a list marker for exactly this reason.

  • -100 + 20 is still -80. No space, so it is arithmetic.
  • 2 * -3 is still -6
  • [1,2] + [3,4] is still a matrix
  • --- is still a horizontal rule, and still skipped

Behavioural change

A bulleted line that previously showed a negative number, or an error, now shows the result of the expression after the marker. That is the intended reading of a bulleted calculation, and the reason the bug was reported.

Verification

  • A 16-case regression spec covering both the fix and the things that had to keep working
  • 6,792 tests across 285 suites, no failures
  • npm run verify green, including the bundled-consumer and sideEffects contracts