Author Topic: MathParser and CrossGraph: an expression parser with an x86-64 JIT, and plotting on top of it  (Read 243 times)

ypisareff

  • Newbie
  • Posts: 1
I have published three MIT-licensed repositories that build with FPC and with Delphi from one source, on Windows and Linux.

MathParser is an expression parser and a virtual machine. A formula is compiled to a flat byte array and evaluated by a linear pass over it, with no allocation on the path of an ordinary formula. On x86-64 an optional accelerator compiles that bytecode to machine code and hands anything it declines back to the interpreter, so the answer is never fast but wrong. It caches by shape: once 2 + 3 has been compiled, 5 + 7 reuses the same script and only writes the numbers into a copy. 249 registered names, your own functions and variables bound by address, and symbolic differentiation.

CrossGraph draws what it computes: a plotting engine plus a visual component. The engine samples curves on worker threads and finds discontinuities, intersections and extrema; it knows nothing about a canvas and builds headless. Cartesian and polar, and surfaces z = f(x, y) with contour lines.

GraphBuilder is a Notepad++ plugin built on both. Alt+G opens a docked panel; point at a line of your file and, if it parses as a formula, it is plotted. The report goes back the other way - to a new tab as Markdown, with the curve embedded as SVG so that it stays text in a text editor and still draws wherever Markdown is rendered.

You can try all of it without installing anything. The live demo is the real engine compiled to WebAssembly with ppcrosswasm32 and running in your browser. That was the part I expected to be hardest and it turned out to be the easiest: the library needs neither the LCL nor LazUtils, the RTL is enough, and it went to wasm32-wasip1 without a single change to the sources.

Where it does not fit, said plainly:

  • The accelerator is x86-64 only. Everywhere else the interpreter answers, at the interpreter's speed.
  • A compiled script is a mutable execution image, not immutable bytecode: evaluation writes into it. One buffer therefore carries one active evaluation. To evaluate in several threads, give each its own Copy(Script) - a plain assignment shares the storage and silently produces wrong numbers. This is written up in the README, with a sample the build matrix compiles and runs.
  • The language is arithmetic, not string handling. ** is the power and ^ is exclusive or, // is a root and not a comment, and comparison answers -1. Everyone gets caught by those at least once.
  • Registration of functions and variables is not thread-safe and is meant to be done before the first evaluation.

The three repositories expect to sit next to each other; the READMEs say which paths and which environment variables override that.

Questions, complaints and patches are welcome - especially about FPC targets I have not tried.
« Last Edit: August 20, 2026, 01:25:02 am by ypisareff »

 

TinyPortal © 2005-2018