Reference
You have the sources. This page is what to do with them - from the first program that prints a number, to the plugin built from scratch, to the engine embedded in a project you already have.
Every command here is one that runs. The parser side is compiled and executed by the build matrix on four targets; the plugin and the demo come from their own build scripts.
Nothing to install, nothing to register. Two paths on the command line and a file with nine lines in it.
program Hero; {$APPTYPE CONSOLE} uses CalcUtils; begin Writeln(AsInteger('2 + 2')); end.
The library is plain Pascal: no build step, no generated headers, no
package manager. Say it lives in C:\lib\pascal-mathparser.
src is the parser, jit is the accelerator. The
second is optional - leave it out and the interpreter answers.
# from the folder that holds the sample cd samples/docs # Delphi dcc64 -U"..\..\src" -NS"System;System.Win;WinApi" hero.dpr ./hero # Free Pascal, any platform fpc -MDelphi -dNOFORMS -dNOGRAPHICS -Fu"../../src/compat" -Fu"../../src" -Fi"../../src" hero.dpr ./hero
It prints 4. That file is
samples/docs/hero.dpr in the repository, and the build matrix
compiles and runs it on every target before a release, so it cannot rot.
src/compat holds stand-ins for units that exist only on Windows,
and -Fi points at the include files. Without either of them the
build stops - measured on Windows as well, where it fails in
Parser.pas long before any GUI unit is reached.
-dNOFORMS -dNOGRAPHICS leave the GUI out. On Windows the build
survives without them; outside Windows it does not, because the thread unit
reaches for Forms. One set that works everywhere is worth more
than two recipes, one of which the reader has to pick correctly.
It is the same set the Linux matrix uses in
tests/build_parser_linux.sh, not a shortened version of it.
Two ways. The first puts the components in the palette and is what most people want; the second is three lines in the project options and leaves the IDE untouched.
packages/delphi/crosspascal_parser.dpk, then
crosspascal_parserjit.dpk. Open each and use
Project, Build. The design-time package requires both, and the IDE
does not build them for you: installing without them stops at
E2202 Required package 'crosspascal_parser' not found.
packages/delphi/crosspascal_parser_dsgn.dpk. It contains the
registration unit and nothing else.
A palette page named CrossPascal appears with the parser, the
calculator, the value list, and the threads. Drop TMathParser
on a form and it works from the Object Inspector.
Tools, Options, Library, Library path - add src and
jit. Without it the IDE finds the components but the compiler
does not find the units.
Project, Options, Delphi Compiler, Search path: add src, and
jit if you want the accelerator. Then create the parser in
code as the samples do. Nothing is installed into the IDE, which is the
point when the project is built on a machine you do not control.
Registering your own function needs a handle variable, and its type must be
TFunctionHandle from ParseTypes - not the plain
NativeInt. On Delphi 12 and later the library defines its own
NativeInt, the var parameter refuses the system one,
and the compiler says only that no overload matches.
Package, Open package file, then
packages/lazarus/crosspascal_parser.lpk. Compile it.
crosspascal_parserjit.lpk, same way. It depends on the first
package, so open them in that order.
Package, Open recent, then Use, Add to project. Installing into the IDE is only needed for the palette.
This used to require LazUtils for a single call. It no longer does: the library needs the RTL and nothing else. A console program on Ubuntu:
# one file, no project, no Lazarus
fpc -MDelphi -O2 -dNOFORMS -dNOGRAPHICS \
-Fu~/pascal-mathparser/src/compat \
-Fu~/pascal-mathparser/src \
-Fu~/pascal-mathparser/jit \
hero.dpr
./hero
The two defines switch off the parts that would otherwise pull in a widgetset: forms and graphics. A console program uses neither.
Compiling this way writes a .ppu and an
.o next to every library source it touches. That is how FPC
works when the units come from -Fu paths, and it is harmless
on its own - but Lazarus refuses to build a package whose source folder
holds compiled units, so delete them before you open
crosspascal_parser.lpk, or keep the console build in a copy
of the repository.
| What you get | Where |
|---|---|
| The interpreter | everywhere, including 32-bit and wasm |
| The IR executor | everywhere the JIT layer is compiled in |
| x86-64 machine code | x86-64 only; elsewhere the tier below answers |
The plugin is the parser and the plotting engine behind a panel. It builds from either compiler.
# from the plugin repository pwsh -File build-lazarus.ps1 # and put it where Notepad++ looks for plugins pwsh -File install.ps1
This is the build that ships. It wants the parser and the plotting engine
cloned beside the plugin, because the project file names them by relative
path, and it wants WEBVIEW4DELPHI pointing at a checkout of
that library - the script registers its Lazarus package itself.
# from the plugin repository pwsh -File build.ps1 # and put it where Notepad++ looks for plugins pwsh -File install.ps1 -Delphi
The same sources through the other compiler; the switch is what tells the installer which of the two to take. It picks up the parser, the accelerator, and the plotting engine from their folders, and no packages need to be installed for it. Both scripts build x64 and only x64: that is what this plugin supports. Notepad++ itself also ships 32-bit and ARM64 builds, and neither of them will load this one.
The demo on this site is not a video and not a screenshot: it is the real parser compiled to WebAssembly, computing in your browser. The same three files drop into any page.
parsewasm.wasm - the engine; wasmhost.js - the
bridge; and the page that talks to it. They sit next to each other and are
loaded as static files. No server code is involved.
WebAssembly is fetched, so file:// will not do. Any static
server works:
python -m http.server 8080
Needs the FPC cross compiler for wasm32-wasip1, built from
the FPC sources. The two commands run in different folders, so each says
where it starts:
# in a checkout of the FPC sources
make crossall crossinstall OS_TARGET=wasip1 CPU_TARGET=wasm32
# in a checkout of this repository
pwsh -File engine/build_wasm.ps1
The x86-64 accelerator does not run in a sandbox: it emits machine code, and a browser executes WebAssembly instead. The demo therefore runs the interpreter, and the speed figures on this site are measured natively and stated as such.
The panel you see in the plugin is a component. It takes formulas as text and draws them; the parser underneath is the same one.
The plotting engine lives beside the parser. Add its folder to the search
path along with src; on Lazarus open
crosspascal_graph.lpk instead.
With the design-time package installed it is on the CrossPascal
palette page. Without it, create the component in code - it is an ordinary
TCustomControl descendant.
The component owns the parser, samples the curve across threads and draws the result. Redirection is what makes the threads safe: every worker gets its own copy of the script, redirected at its own variables.
On FPC the drawing goes through the LCL canvas, so a project with the plotting component does need Lazarus - unlike the parser alone, which does not.