Skip to content

2.0.0

Choose a tag to compare

@LiamRiddell LiamRiddell released this 11 Aug 21:51
· 3 commits to main since this release
e8ca1e5

Solve 2.0

This release replaces the engine underneath Solve. The old Ohm.js grammar is
gone. In its place is solve-engine,
a lexer, parser and bytecode virtual machine, built from scratch and published
as its own package so it can be tested, versioned and improved independently
of the plugin.

Speed

The old engine walked a parse tree on every keystroke. The new one compiles
each line to bytecode once and runs it on a small virtual machine, with the
compiled program cached per line. A dependency graph tracks which lines refer
to which others, so editing one line re-evaluates only the lines that actually
depend on it, not the whole document.

Resilience

A calculator has to accept whatever a person happens to type, mid-thought,
one keystroke at a time. The new engine is built around that assumption
rather than around it. Expression length, nesting depth, instruction count
and stack depth are all bounded, and a limit being hit produces a named,
recoverable error instead of a hang or a crash. The engine has been fuzzed
against millions of generated and mutated expressions, checking three things
every time: the process does not die, nothing hangs, and every failure comes
back as a proper error rather than a raw exception.

That resilience is visible in the plugin too. A line that fails to evaluate
no longer shows an error inline. It stays quiet until it resolves, the same
way a pending async result does.

What the new engine understands

Everything the old engine could do, and a fair amount it could not:

10 + 20 / 200 * 4              // arithmetic
15% of 2400                    // percentages
100cm + 2m                     // units of measurement
$100 + $250                    // currency
days since 01/01/2023          // dates and durations
next friday                    // natural date phrasing
2d6 + 3                        // dice
if 5 > 3 then 100 else 200     // conditionals
[1, 2; 3, 4] * [5, 6; 7, 8]    // matrices

The full list, kept in sync with the engine itself rather than a separate
wiki, lives in the
syntax reference.

Other changes in this release

  • Explicit mode, dropped during the migration, is back.
  • Provider enable and disable toggles now actually turn the corresponding
    engine package off, rather than doing nothing.
  • Result animations are wired up and configurable.
  • A pass through every settings section removed the ones that had nothing
    left to connect to in the new engine, and fixed the ones that did.
  • The README has been rewritten to match solve-engine's own documentation
    style.

Going forward

Obsidian Solve now tracks solve-engine as a dependency and picks up new
releases automatically, once each one has been built and tested against this
plugin. New syntax and engine features will show up in solve-engine's own
changelog and documentation first. This repository is now just the Obsidian
integration: settings, rendering and editor behaviour on top of the engine.